'use client';
import { jsx as _jsx } from "react/jsx-runtime";
import { accentTokensToCssVars, generateAdminThemeTokens, } from '@actuate-media/cms-core/appearance';
import { createContext, useContext, useState, useEffect, useCallback } from 'react';
/** Curated content-font options. Applied as family strings (no web-font load). */
export const AVAILABLE_FONTS = ['DM Sans', 'Inter', 'Geist', 'System UI'];
const SYSTEM_STACK = "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";
const FONT_STACKS = {
    'DM Sans': `'DM Sans', ${SYSTEM_STACK}`,
    Inter: `'Inter', ${SYSTEM_STACK}`,
    Geist: `'Geist', ${SYSTEM_STACK}`,
    'System UI': SYSTEM_STACK,
};
function fontStack(font) {
    return FONT_STACKS[font] ?? `'${font}', ${SYSTEM_STACK}`;
}
const DEFAULT_BRAND = {
    primaryUrl: null,
    markUrl: null,
    darkUrl: null,
    initials: 'A',
};
const ThemeContext = createContext({
    theme: 'system',
    resolvedTheme: 'light',
    setTheme: () => { },
    accent: 'purple',
    setAccent: () => { },
    density: 'default',
    setDensity: () => { },
    font: 'DM Sans',
    setFont: () => { },
    reduceMotion: false,
    setReduceMotion: () => { },
    adminBrand: DEFAULT_BRAND,
    setAdminBrand: () => { },
    applyAppearance: () => { },
});
export function useTheme() {
    return useContext(ThemeContext);
}
function getSystemTheme() {
    if (typeof window === 'undefined')
        return 'light';
    return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}
function resolveTheme(theme) {
    return theme === 'system' ? getSystemTheme() : theme;
}
const KEY_THEME = 'actuate-theme';
const KEY_ACCENT = 'actuate-accent';
const KEY_DENSITY = 'actuate-density';
const KEY_FONT = 'actuate-font';
const KEY_MOTION = 'actuate-reduce-motion';
const KEY_BRAND = 'actuate-admin-brand';
function adminRootEl() {
    return document.querySelector('.actuate-admin');
}
function applyColorMode(resolved) {
    const el = adminRootEl();
    if (!el)
        return;
    el.classList.toggle('dark', resolved === 'dark');
}
function applyAccent(accent, resolved) {
    const el = adminRootEl();
    if (!el)
        return;
    const vars = accentTokensToCssVars(generateAdminThemeTokens({ adminAccentColor: accent }, resolved));
    for (const [name, value] of Object.entries(vars))
        el.style.setProperty(name, value);
}
function applyDensity(density) {
    const el = adminRootEl();
    if (!el)
        return;
    el.setAttribute('data-density', density);
}
function applyFont(font) {
    const el = adminRootEl();
    if (!el)
        return;
    el.style.setProperty('--actuate-admin-font', fontStack(font));
}
function applyReduceMotion(value) {
    const el = adminRootEl();
    if (!el)
        return;
    el.classList.toggle('reduce-motion', value);
}
export function ThemeProvider({ children, defaultDarkMode }) {
    const [theme, setThemeState] = useState('system');
    const [resolvedTheme, setResolvedTheme] = useState('light');
    const [accent, setAccentState] = useState('purple');
    const [density, setDensityState] = useState('default');
    const [font, setFontState] = useState('DM Sans');
    const [reduceMotion, setReduceMotionState] = useState(false);
    const [adminBrand, setAdminBrandState] = useState(DEFAULT_BRAND);
    // Hydrate from localStorage on mount and apply everything to the DOM.
    useEffect(() => {
        const storedTheme = localStorage.getItem(KEY_THEME);
        let initialTheme;
        if (storedTheme && ['light', 'dark', 'system'].includes(storedTheme)) {
            initialTheme = storedTheme;
        }
        else if (defaultDarkMode === true) {
            initialTheme = 'dark';
        }
        else if (defaultDarkMode === false) {
            initialTheme = 'light';
        }
        else {
            initialTheme = 'system';
        }
        const resolved = resolveTheme(initialTheme);
        const storedAccent = localStorage.getItem(KEY_ACCENT) || 'purple';
        const storedDensity = localStorage.getItem(KEY_DENSITY) || 'default';
        const storedFont = localStorage.getItem(KEY_FONT) || 'DM Sans';
        const storedMotion = localStorage.getItem(KEY_MOTION) === 'true';
        let storedBrand = DEFAULT_BRAND;
        try {
            const raw = localStorage.getItem(KEY_BRAND);
            if (raw)
                storedBrand = { ...DEFAULT_BRAND, ...JSON.parse(raw) };
        }
        catch {
            // Ignore malformed cache.
        }
        setThemeState(initialTheme);
        setResolvedTheme(resolved);
        setAccentState(storedAccent);
        setDensityState(storedDensity);
        setFontState(storedFont);
        setReduceMotionState(storedMotion);
        setAdminBrandState(storedBrand);
        applyColorMode(resolved);
        applyAccent(storedAccent, resolved);
        applyDensity(storedDensity);
        applyFont(storedFont);
        applyReduceMotion(storedMotion);
    }, [defaultDarkMode]);
    // Follow the OS color scheme while in `system` mode (re-applies accent too,
    // since presets differ between light and dark).
    useEffect(() => {
        const mq = window.matchMedia('(prefers-color-scheme: dark)');
        const handler = () => {
            if (theme === 'system') {
                const resolved = getSystemTheme();
                setResolvedTheme(resolved);
                applyColorMode(resolved);
                applyAccent(accent, resolved);
            }
        };
        mq.addEventListener('change', handler);
        return () => mq.removeEventListener('change', handler);
    }, [theme, accent]);
    const setTheme = useCallback((next) => {
        setThemeState(next);
        localStorage.setItem(KEY_THEME, next);
        const resolved = resolveTheme(next);
        setResolvedTheme(resolved);
        applyColorMode(resolved);
        applyAccent(accent, resolved);
    }, [accent]);
    const setAccent = useCallback((next) => {
        setAccentState(next);
        localStorage.setItem(KEY_ACCENT, next);
        applyAccent(next, resolvedTheme);
    }, [resolvedTheme]);
    const setDensity = useCallback((next) => {
        setDensityState(next);
        localStorage.setItem(KEY_DENSITY, next);
        applyDensity(next);
    }, []);
    const setFont = useCallback((next) => {
        setFontState(next);
        localStorage.setItem(KEY_FONT, next);
        applyFont(next);
    }, []);
    const setReduceMotion = useCallback((next) => {
        setReduceMotionState(next);
        localStorage.setItem(KEY_MOTION, String(next));
        applyReduceMotion(next);
    }, []);
    const setAdminBrand = useCallback((next) => {
        setAdminBrandState(next);
        localStorage.setItem(KEY_BRAND, JSON.stringify(next));
    }, []);
    // Apply a full snapshot live (Appearance tab on load/save). Persists to
    // localStorage so the choice survives reloads even before the next fetch.
    const applyAppearance = useCallback((snapshot) => {
        if (snapshot.theme !== undefined)
            setTheme(snapshot.theme);
        if (snapshot.accent !== undefined)
            setAccent(snapshot.accent);
        if (snapshot.density !== undefined)
            setDensity(snapshot.density);
        if (snapshot.font !== undefined)
            setFont(snapshot.font);
        if (snapshot.reduceMotion !== undefined)
            setReduceMotion(snapshot.reduceMotion);
        if (snapshot.adminBrand !== undefined)
            setAdminBrand(snapshot.adminBrand);
    }, [setTheme, setAccent, setDensity, setFont, setReduceMotion, setAdminBrand]);
    return (_jsx(ThemeContext.Provider, { value: {
            theme,
            resolvedTheme,
            setTheme,
            accent,
            setAccent,
            density,
            setDensity,
            font,
            setFont,
            reduceMotion,
            setReduceMotion,
            adminBrand,
            setAdminBrand,
            applyAppearance,
        }, children: children }));
}
//# sourceMappingURL=ThemeProvider.js.map