import {
    createContext,
    useCallback,
    useEffect,
    useMemo,
    useState,
    type ReactNode,
} from 'react';
import CssBaseline from '@mui/material/CssBaseline';
import { ThemeProvider } from '@mui/material/styles';
import { getTheme } from '../theme';

const STORAGE_KEY = 'theme-mode';

function readStoredMode(): 'light' | 'dark' | null {
    if (typeof window === 'undefined') {
        return null;
    }
    const v = localStorage.getItem(STORAGE_KEY);
    if (v === 'dark' || v === 'light') {
        return v;
    }
    return null;
}

function systemPrefersDark(): boolean {
    if (typeof window === 'undefined') {
        return false;
    }
    return window.matchMedia('(prefers-color-scheme: dark)').matches;
}

function initialMode(): 'light' | 'dark' {
    return readStoredMode() ?? (systemPrefersDark() ? 'dark' : 'light');
}

export type ThemeModeContextValue = {
    mode: 'light' | 'dark';
    toggleTheme: () => void;
};

export const ThemeModeContext = createContext<ThemeModeContextValue>({
    mode: 'light',
    toggleTheme: () => {},
});

type Props = {
    children: ReactNode;
};

export default function ThemeContextProvider({ children }: Props) {
    const [mode, setMode] = useState<'light' | 'dark'>(initialMode);

    const toggleTheme = useCallback(() => {
        setMode((prev) => {
            const next = prev === 'light' ? 'dark' : 'light';
            localStorage.setItem(STORAGE_KEY, next);
            return next;
        });
    }, []);

    useEffect(() => {
        document.documentElement.classList.toggle('dark', mode === 'dark');
    }, [mode]);

    const theme = useMemo(() => getTheme(mode), [mode]);

    const value = useMemo(
        () => ({ mode, toggleTheme }),
        [mode, toggleTheme],
    );

    return (
        <ThemeModeContext.Provider value={value}>
            <ThemeProvider theme={theme}>
                <CssBaseline />
                {children}
            </ThemeProvider>
        </ThemeModeContext.Provider>
    );
}
