import { createContext, useContext, useEffect, useState, type ReactNode } from 'react' export type Theme = 'light' | 'dark' | 'system' type ThemeContextValue = { theme: Theme setTheme: (theme: Theme) => void } const STORAGE_KEY = 'tw-theme' const ThemeContext = createContext(undefined) function resolve(theme: Theme): 'light' | 'dark' { if (theme === 'system') { return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light' } return theme } function applyTheme(theme: Theme) { const root = document.documentElement root.classList.toggle('dark', resolve(theme) === 'dark') } export function ThemeProvider({ children }: { children: ReactNode }) { const [theme, setThemeState] = useState( () => (localStorage.getItem(STORAGE_KEY) as Theme | null) ?? 'dark', ) useEffect(() => { applyTheme(theme) if (theme !== 'system') return const media = window.matchMedia('(prefers-color-scheme: dark)') const onChange = () => applyTheme('system') media.addEventListener('change', onChange) return () => media.removeEventListener('change', onChange) }, [theme]) const setTheme = (next: Theme) => { localStorage.setItem(STORAGE_KEY, next) setThemeState(next) } return {children} } export function useTheme(): ThemeContextValue { const ctx = useContext(ThemeContext) if (!ctx) throw new Error('useTheme must be used within ThemeProvider') return ctx }