import { createContext, useContext, useEffect, useState, ReactNode, useCallback } from 'react';

export type ThemeMode = 'light' | 'dark' | 'system';
export type ColorScheme = 'blue' | 'purple' | 'green' | 'orange';

interface ThemeContextType {
  mode: ThemeMode;
  colorScheme: ColorScheme;
  resolvedTheme: 'light' | 'dark';
  setMode: (mode: ThemeMode) => void;
  setColorScheme: (scheme: ColorScheme) => void;
}

const ThemeContext = createContext<ThemeContextType | undefined>(undefined);

const STORAGE_KEY = 'vip-theme';

interface StoredTheme {
  mode: ThemeMode;
  colorScheme: ColorScheme;
}

function getStoredTheme(): StoredTheme {
  try {
    const stored = localStorage.getItem(STORAGE_KEY);
    if (stored) {
      const parsed = JSON.parse(stored);
      return {
        mode: parsed.mode || 'system',
        colorScheme: parsed.colorScheme || 'blue',
      };
    }
  } catch (e) {
    console.warn('[THEME] Failed to parse stored theme:', e);
  }
  return { mode: 'system', colorScheme: 'blue' };
}

function getSystemTheme(): 'light' | 'dark' {
  if (typeof window !== 'undefined') {
    return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
  }
  return 'light';
}

export function ThemeProvider({ children }: { children: ReactNode }) {
  const [mode, setModeState] = useState<ThemeMode>(() => getStoredTheme().mode);
  const [colorScheme, setColorSchemeState] = useState<ColorScheme>(() => getStoredTheme().colorScheme);
  const [systemTheme, setSystemTheme] = useState<'light' | 'dark'>(() => getSystemTheme());

  // Compute resolved theme
  const resolvedTheme = mode === 'system' ? systemTheme : mode;

  // Listen for system theme changes
  useEffect(() => {
    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');

    const handleChange = (e: MediaQueryListEvent) => {
      setSystemTheme(e.matches ? 'dark' : 'light');
    };

    mediaQuery.addEventListener('change', handleChange);
    return () => mediaQuery.removeEventListener('change', handleChange);
  }, []);

  // Apply theme to document
  useEffect(() => {
    const root = document.documentElement;

    // Apply dark mode class
    if (resolvedTheme === 'dark') {
      root.classList.add('dark');
    } else {
      root.classList.remove('dark');
    }

    // Apply color scheme
    root.dataset.theme = colorScheme;

    // Add transition class after initial load to prevent FOUC
    requestAnimationFrame(() => {
      root.classList.add('theme-transition');
    });
  }, [resolvedTheme, colorScheme]);

  // Persist theme to localStorage
  useEffect(() => {
    try {
      localStorage.setItem(STORAGE_KEY, JSON.stringify({ mode, colorScheme }));
    } catch (e) {
      console.warn('[THEME] Failed to save theme:', e);
    }
  }, [mode, colorScheme]);

  const setMode = useCallback((newMode: ThemeMode) => {
    setModeState(newMode);
  }, []);

  const setColorScheme = useCallback((newScheme: ColorScheme) => {
    setColorSchemeState(newScheme);
  }, []);

  return (
    <ThemeContext.Provider
      value={{
        mode,
        colorScheme,
        resolvedTheme,
        setMode,
        setColorScheme,
      }}
    >
      {children}
    </ThemeContext.Provider>
  );
}

export function useTheme() {
  const context = useContext(ThemeContext);
  if (context === undefined) {
    throw new Error('useTheme must be used within a ThemeProvider');
  }
  return context;
}
