'use client';

import {
  createContext,
  useContext,
  useEffect,
  useState,
  ReactNode,
} from 'react';
import { updateViewPreferences } from '@/actions/preferences';
import { useToast } from '@/components/ui/Toast';
import {
  Theme,
  THEME_CONFIG,
  getNextDarkTheme,
  THEME_NAMES,
  getThemeIcon,
} from '@/lib/ui-config';
import { useSession } from 'next-auth/react';

interface ThemeContextType {
  theme: Theme;
  toggleTheme: () => void;
  setTheme: (theme: Theme) => void;
  cycleDarkThemes: () => void;
  userPreferredTheme: Theme;
}

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

interface ThemeProviderProps {
  children: ReactNode;
  initialTheme?: Theme;
  userPreferredTheme?: Theme;
}

export function ThemeProvider({
  children,
  initialTheme = 'dark',
  userPreferredTheme: initialUserPreferredTheme = 'dark',
}: ThemeProviderProps) {
  const [theme, setThemeState] = useState<Theme>(initialTheme);
  const [userPreferredTheme, setUserPreferredTheme] = useState<Theme>(
    initialUserPreferredTheme
  );
  const [mounted, setMounted] = useState(false);
  const { showToast } = useToast();
  const { data: session } = useSession();

  // Hydration safe initialization
  useEffect(() => {
    setMounted(true);
  }, []);

  // Apply theme class to document
  useEffect(() => {
    if (mounted) {
      // Remove all existing theme classes
      document.documentElement.classList.remove(...THEME_CONFIG.allThemes);
      // Add the current theme class
      document.documentElement.classList.add(theme);
    }
  }, [theme, mounted]);

  const toggleTheme = async () => {
    // Toggle between light and the user's chosen dark theme
    const newTheme = theme === 'light' ? userPreferredTheme : 'light';
    setThemeState(newTheme);

    // Sauvegarder en base seulement si l'utilisateur est authentifié
    if (session?.user?.id) {
      try {
        const result = await updateViewPreferences({
          theme: newTheme,
        });
        if (!result.success) {
          console.error('Erreur lors de la sauvegarde du thème:', result.error);
        }
      } catch (error) {
        console.error('Erreur lors de la sauvegarde du thème:', error);
      }
    }

    // Afficher le toast avec le nom du thème
    showToast(`Thème: ${THEME_NAMES[newTheme]}`, 2000, getThemeIcon(newTheme));
  };

  const setTheme = async (newTheme: Theme) => {
    setThemeState(newTheme);

    // Si ce n'est pas le thème light, c'est le thème préféré de l'utilisateur
    if (newTheme !== 'light') {
      setUserPreferredTheme(newTheme);
    }

    // Sauvegarder en base seulement si l'utilisateur est authentifié
    if (session?.user?.id) {
      try {
        const result = await updateViewPreferences({
          theme: newTheme,
        });
        if (!result.success) {
          console.error('Erreur lors de la sauvegarde du thème:', result.error);
        }
      } catch (error) {
        console.error('Erreur lors de la sauvegarde du thème:', error);
      }
    }

    // Afficher le toast avec le nom du thème
    showToast(`Thème: ${THEME_NAMES[newTheme]}`, 2000, getThemeIcon(newTheme));
  };

  const cycleDarkThemes = async () => {
    // Si on est sur light, on passe au premier thème dark
    if (theme === 'light') {
      await setTheme(THEME_CONFIG.darkThemes[0]);
      return;
    }

    // Sinon, on passe au thème dark suivant
    const nextTheme = getNextDarkTheme(theme);
    await setTheme(nextTheme);
  };

  return (
    <ThemeContext.Provider
      value={{
        theme,
        toggleTheme,
        setTheme,
        cycleDarkThemes,
        userPreferredTheme,
      }}
    >
      <div className={mounted ? theme : initialTheme}>{children}</div>
    </ThemeContext.Provider>
  );
}

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