// theme.js
// Applies the persisted theme on page load and exposes a toggler.
//
// Precedence: explicit user choice (localStorage) > OS preference (prefers-color-scheme) > light default.
// Listens for OS-theme changes so flipping Windows dark/light mode auto-updates the page,
// unless the user has explicitly toggled (in which case we respect their choice forever).

(function () {
    const KEY = 'wsm-theme';
    const sysQuery = window.matchMedia ? window.matchMedia('(prefers-color-scheme: dark)') : null;

    function applyTheme(t) {
        if (t === 'dark') document.documentElement.setAttribute('data-theme', 'dark');
        else document.documentElement.removeAttribute('data-theme');
    }

    function effectiveTheme() {
        const saved = localStorage.getItem(KEY);
        if (saved === 'dark' || saved === 'light') return saved;
        if (sysQuery && sysQuery.matches) return 'dark';
        return 'light';
    }

    applyTheme(effectiveTheme());

    // React to OS theme changes — unless the user picked an explicit preference.
    if (sysQuery && typeof sysQuery.addEventListener === 'function') {
        sysQuery.addEventListener('change', () => {
            if (!localStorage.getItem(KEY)) applyTheme(effectiveTheme());
        });
    }

    // Blazor 8's enhanced navigation swaps body content on internal link clicks but
    // doesn't re-execute scripts that already ran. Worse, it merges <html> attributes
    // from the new server response — which doesn't include data-theme, so it gets
    // wiped. Hook the enhancedload event to re-apply the theme after every soft nav.
    document.addEventListener('enhancedload', () => applyTheme(effectiveTheme()));

    // Belt-and-suspenders: a MutationObserver that watches for our data-theme being
    // stripped and immediately re-applies. Catches cases where enhancedload doesn't fire
    // (full-page reloads inside the wrapper, history.pushState, etc.).
    if (typeof MutationObserver !== 'undefined') {
        const obs = new MutationObserver(() => {
            const want = effectiveTheme();
            const have = document.documentElement.getAttribute('data-theme');
            if (want === 'dark' && have !== 'dark') applyTheme('dark');
            if (want === 'light' && have === 'dark') applyTheme('light');
        });
        obs.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] });
    }

    window.wsmTheme = {
        get: effectiveTheme,
        toggle: function () {
            const next = effectiveTheme() === 'dark' ? 'light' : 'dark';
            localStorage.setItem(KEY, next);
            applyTheme(next);
            return next;
        },
        set: function (t) {
            if (t !== 'dark' && t !== 'light') return;
            localStorage.setItem(KEY, t);
            applyTheme(t);
        },
        reset: function () {
            localStorage.removeItem(KEY);
            applyTheme(effectiveTheme());
        }
    };
})();
