/**
 * Tests for mobile-navigation.js — pure helpers on the MobileNavigation class.
 *
 * checkViewport drives whether the mobile bottom-nav is shown at all,
 * and isCurrentPage decides which tab is highlighted. Both are pure
 * reads of `window.innerWidth` / `window.location.pathname`, so they
 * are testable without touching the rest of the class wiring.
 *
 * The module auto-instantiates a singleton when imported (`initMobileNav`
 * runs immediately because happy-dom reports `document.readyState === 'complete'`).
 * That constructor path renders HTML that references the global `URLS`
 * config, so we stub it before the dynamic import.
 */

let MobileNavigation;

beforeAll(async () => {
    // Minimal URLS stub — only the PAGES keys the constructor's bottom-nav
    // and sheet-menu templates dereference.
    globalThis.URLS = {
        PAGES: {
            HOME: '/',
            HISTORY: '/history/',
            LIBRARY: '/library',
            NEWS: '/news',
            NEWS_SUBSCRIPTIONS: '/news/subscriptions',
            COLLECTIONS: '/library/collections',
            METRICS: '/metrics',
            BENCHMARK: '/benchmark',
            BENCHMARK_RESULTS: '/benchmark/results',
            EMBEDDING_SETTINGS: '/settings/embedding',
            SETTINGS: '/settings',
        },
    };

    await import('@js/mobile-navigation.js');
    MobileNavigation = window.MobileNavigation;
});

describe('MobileNavigation.checkViewport', () => {
    let originalInnerWidth;

    beforeEach(() => {
        originalInnerWidth = window.innerWidth;
    });

    afterEach(() => {
        Object.defineProperty(window, 'innerWidth', {
            value: originalInnerWidth,
            configurable: true,
            writable: true,
        });
    });

    function setInnerWidth(px) {
        Object.defineProperty(window, 'innerWidth', {
            value: px,
            configurable: true,
            writable: true,
        });
    }

    it('returns true and sets state.isVisible=true below the breakpoint', () => {
        const nav = new MobileNavigation();
        setInnerWidth(500);
        expect(nav.checkViewport()).toBe(true);
        expect(nav.state.isVisible).toBe(true);
    });

    it('returns false and sets state.isVisible=false at the breakpoint (768)', () => {
        // Uses strict < (not <=) — 768px is tablet, sidebar should be visible.
        const nav = new MobileNavigation();
        setInnerWidth(768);
        expect(nav.checkViewport()).toBe(false);
        expect(nav.state.isVisible).toBe(false);
    });

    it('returns false above the breakpoint', () => {
        const nav = new MobileNavigation();
        setInnerWidth(1280);
        expect(nav.checkViewport()).toBe(false);
        expect(nav.state.isVisible).toBe(false);
    });

    it('respects a custom breakpoint passed via options', () => {
        const nav = new MobileNavigation({ breakpoint: 1024 });
        setInnerWidth(900);
        expect(nav.checkViewport()).toBe(true);
        setInnerWidth(1024);
        expect(nav.checkViewport()).toBe(false);
    });
});

describe('MobileNavigation.isCurrentPage', () => {
    let originalLocation;

    beforeAll(() => {
        originalLocation = window.location;
    });

    afterAll(() => {
        Object.defineProperty(window, 'location', {
            value: originalLocation,
            configurable: true,
        });
    });

    function setPath(pathname) {
        Object.defineProperty(window, 'location', {
            value: { pathname },
            configurable: true,
            writable: true,
        });
    }

    function nav() {
        return new MobileNavigation();
    }

    it('treats the research tab as active only on the bare root path', () => {
        setPath('/');
        expect(nav().isCurrentPage({ id: 'research' })).toBe(true);

        setPath('/something');
        expect(nav().isCurrentPage({ id: 'research' })).toBe(false);
    });

    it('matches the history tab on /history and any sub-path', () => {
        setPath('/history');
        expect(nav().isCurrentPage({ id: 'history' })).toBe(true);

        setPath('/history/abc-123');
        expect(nav().isCurrentPage({ id: 'history' })).toBe(true);

        setPath('/');
        expect(nav().isCurrentPage({ id: 'history' })).toBe(false);
    });

    it('matches the library tab on /library prefix', () => {
        setPath('/library');
        expect(nav().isCurrentPage({ id: 'library' })).toBe(true);

        setPath('/library/collections/42');
        expect(nav().isCurrentPage({ id: 'library' })).toBe(true);
    });

    it('matches the metrics tab on /metrics prefix', () => {
        setPath('/metrics');
        expect(nav().isCurrentPage({ id: 'metrics' })).toBe(true);

        setPath('/metrics/dashboard');
        expect(nav().isCurrentPage({ id: 'metrics' })).toBe(true);
    });

    it('matches the news tab on /news prefix', () => {
        setPath('/news');
        expect(nav().isCurrentPage({ id: 'news' })).toBe(true);

        setPath('/news/subscriptions');
        expect(nav().isCurrentPage({ id: 'news' })).toBe(true);
    });

    it('returns false for unknown tab ids', () => {
        setPath('/');
        expect(nav().isCurrentPage({ id: 'unknown' })).toBe(false);
    });

    it('does not cross-match: /library should not light up history or news', () => {
        setPath('/library');
        expect(nav().isCurrentPage({ id: 'history' })).toBe(false);
        expect(nav().isCurrentPage({ id: 'news' })).toBe(false);
    });
});
