'use client'; import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'; export type ThemeMode = 'light' | 'dim'; const THEME_STORAGE_KEY = 'gooseek_theme'; function readStoredTheme(): ThemeMode | null { try { const v = localStorage.getItem(THEME_STORAGE_KEY); if (v === 'light' || v === 'dim') return v; return null; } catch { return null; } } function prefersDark(): boolean { if (typeof window === 'undefined') return false; return !!window.matchMedia?.('(prefers-color-scheme: dark)')?.matches; } function applyTheme(theme: ThemeMode): void { if (typeof document === 'undefined') return; const root = document.documentElement; if (theme === 'dim') root.classList.add('theme-dim'); else root.classList.remove('theme-dim'); try { localStorage.setItem(THEME_STORAGE_KEY, theme); } catch { // ignore storage failures (private mode, quota, etc.) } } function resolveInitialTheme(): ThemeMode { if (typeof document !== 'undefined' && document.documentElement.classList.contains('theme-dim')) { return 'dim'; } const stored = typeof window !== 'undefined' ? readStoredTheme() : null; if (stored) return stored; return prefersDark() ? 'dim' : 'light'; } type ThemeContextValue = { theme: ThemeMode; setTheme: (theme: ThemeMode) => void; toggleTheme: () => void; }; const ThemeContext = createContext(null); export function ThemeProvider({ children }: { children: React.ReactNode }) { const [theme, setThemeState] = useState('light'); useEffect(() => { const initial = resolveInitialTheme(); setThemeState(initial); applyTheme(initial); }, []); const setTheme = useCallback((next: ThemeMode) => { setThemeState(next); applyTheme(next); }, []); const toggleTheme = useCallback(() => { setTheme(theme === 'light' ? 'dim' : 'light'); }, [theme, setTheme]); useEffect(() => { const onStorage = (e: StorageEvent) => { if (e.key !== THEME_STORAGE_KEY) return; const v = e.newValue; if (v !== 'light' && v !== 'dim') return; setThemeState(v); applyTheme(v); }; window.addEventListener('storage', onStorage); return () => window.removeEventListener('storage', onStorage); }, []); const value = useMemo(() => ({ theme, setTheme, toggleTheme }), [theme, setTheme, toggleTheme]); return {children}; } export function useTheme(): ThemeContextValue { const ctx = useContext(ThemeContext); if (!ctx) { throw new Error('useTheme must be used within ThemeProvider'); } return ctx; }