import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react' const STORAGE_KEY = 'zui-theme' export type Theme = 'light' | 'dark' function readStored(): Theme | null { try { const s = localStorage.getItem(STORAGE_KEY) if (s === 'light' || s === 'dark') return s } catch (_) {} return null } function systemPrefersDark(): boolean { try { return window.matchMedia('(prefers-color-scheme: dark)').matches } catch (_) { return false } } type ThemeContextValue = { theme: Theme setTheme: (theme: Theme) => void toggleTheme: () => void } const ThemeContext = createContext(null) export function ThemeProvider({ children }: { children: React.ReactNode }) { const [theme, setThemeState] = useState(() => { const stored = readStored() if (stored) return stored return systemPrefersDark() ? 'dark' : 'light' }) useEffect(() => { const root = document.documentElement if (theme === 'dark') { root.classList.add('dark') } else { root.classList.remove('dark') } }, [theme]) useEffect(() => { const m = window.matchMedia('(prefers-color-scheme: dark)') const handler = () => { if (readStored() != null) return setThemeState(m.matches ? 'dark' : 'light') } m.addEventListener('change', handler) return () => m.removeEventListener('change', handler) }, []) const setTheme = useCallback((next: Theme) => { setThemeState(next) try { localStorage.setItem(STORAGE_KEY, next) } catch (_) {} }, []) const toggleTheme = useCallback(() => { setThemeState((prev) => { const next = prev === 'light' ? 'dark' : 'light' try { localStorage.setItem(STORAGE_KEY, next) } catch (_) {} return next }) }, []) 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 }