/**
 * Tests for services/help.js
 *
 * Tests the HelpService for collapsible help panels:
 * togglePanel, dismissPanel, isPanelDismissed, expandAll, collapseAll, reset.
 */

let HelpService;

beforeAll(async () => {
    // Stub fetch — initPanelStates calls /settings/api/bulk on init
    globalThis.fetch = vi.fn(() =>
        Promise.resolve({
            ok: true,
            json: () => Promise.resolve({ success: true, settings: {} }),
        })
    );
    window.api = { getCsrfToken: () => 'test-token' };
    window.ui = { showMessage: vi.fn() };

    await import('@js/services/help.js');
    HelpService = window.HelpService;
});

afterEach(() => {
    // Clean up any panels created in tests
    document.querySelectorAll('.ldr-help-panel').forEach(p => p.remove());
    localStorage.clear();
});

describe('HelpService', () => {
    function createPanel(id, collapsed = false) {
        const panel = document.createElement('div');
        panel.className = 'ldr-help-panel' + (collapsed ? ' collapsed' : '');
        panel.id = 'help-panel-' + id;
        panel.setAttribute('data-panel-id', id);

        const header = document.createElement('div');
        header.className = 'ldr-help-panel-header';
        header.setAttribute('aria-expanded', collapsed ? 'false' : 'true');
        panel.appendChild(header);

        document.body.appendChild(panel);
        return panel;
    }

    describe('togglePanel', () => {
        it('toggles the collapsed class', () => {
            const panel = createPanel('test1');
            expect(panel.classList.contains('collapsed')).toBe(false);

            HelpService.togglePanel('test1');
            expect(panel.classList.contains('collapsed')).toBe(true);

            HelpService.togglePanel('test1');
            expect(panel.classList.contains('collapsed')).toBe(false);
        });

        it('updates aria-expanded on header', () => {
            const panel = createPanel('test2');
            const header = panel.querySelector('.ldr-help-panel-header');

            HelpService.togglePanel('test2');
            expect(header.getAttribute('aria-expanded')).toBe('false');

            HelpService.togglePanel('test2');
            expect(header.getAttribute('aria-expanded')).toBe('true');
        });

        it('persists collapsed state to localStorage', () => {
            createPanel('test3');
            HelpService.togglePanel('test3');
            expect(localStorage.getItem('ldr_panel_collapsed_test3')).toBe('true');

            HelpService.togglePanel('test3');
            expect(localStorage.getItem('ldr_panel_collapsed_test3')).toBe('false');
        });

        it('does nothing for non-existent panel', () => {
            const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
            expect(() => HelpService.togglePanel('nonexistent')).not.toThrow();
            warnSpy.mockRestore();
        });
    });

    describe('expandAll', () => {
        it('removes collapsed class from all panels', () => {
            const p1 = createPanel('e1', true);
            const p2 = createPanel('e2', true);
            const p3 = createPanel('e3', false);

            HelpService.expandAll();

            expect(p1.classList.contains('collapsed')).toBe(false);
            expect(p2.classList.contains('collapsed')).toBe(false);
            expect(p3.classList.contains('collapsed')).toBe(false);
        });

        it('updates aria-expanded to true on all expanded panels', () => {
            const p = createPanel('e4', true);
            HelpService.expandAll();
            const header = p.querySelector('.ldr-help-panel-header');
            expect(header.getAttribute('aria-expanded')).toBe('true');
        });
    });

    describe('collapseAll', () => {
        it('adds collapsed class to all panels', () => {
            const p1 = createPanel('c1', false);
            const p2 = createPanel('c2', false);

            HelpService.collapseAll();

            expect(p1.classList.contains('collapsed')).toBe(true);
            expect(p2.classList.contains('collapsed')).toBe(true);
        });

        it('updates aria-expanded to false', () => {
            const p = createPanel('c3', false);
            HelpService.collapseAll();
            const header = p.querySelector('.ldr-help-panel-header');
            expect(header.getAttribute('aria-expanded')).toBe('false');
        });

        it('does not affect already-collapsed panels', () => {
            const p = createPanel('c4', true);
            HelpService.collapseAll();
            expect(p.classList.contains('collapsed')).toBe(true);
        });
    });

    describe('isPanelDismissed', () => {
        it('returns false for unknown panels', () => {
            expect(HelpService.isPanelDismissed('unknown')).toBe(false);
        });
    });

    describe('dismissPanel', () => {
        it('hides the panel and marks it dismissed', async () => {
            const panel = createPanel('dismiss1');
            globalThis.fetch = vi.fn(() =>
                Promise.resolve({ ok: true, status: 200 })
            );

            await HelpService.dismissPanel('dismiss1');
            expect(panel.style.display).toBe('none');
            expect(HelpService.isPanelDismissed('dismiss1')).toBe(true);
        });
    });
});
