'use client';

import {
  createContext,
  useContext,
  useEffect,
  useState,
  ReactNode,
} from 'react';
import { useUserPreferences } from './UserPreferencesContext';
import {
  PRESET_BACKGROUNDS,
  BACKGROUND_NAMES,
  TOAST_ICONS,
  getNextBackground,
} from '@/lib/ui-config';
import { useSession } from 'next-auth/react';
import { useToast } from '@/components/ui/Toast';

interface BackgroundContextType {
  backgroundImage: string | undefined;
  setBackgroundImage: (image: string | undefined) => void;
  cycleBackground: () => void;
}

const BackgroundContext = createContext<BackgroundContextType | undefined>(
  undefined
);

interface BackgroundProviderProps {
  children: ReactNode;
}

export function BackgroundProvider({ children }: BackgroundProviderProps) {
  const { preferences, updateViewPreferences } = useUserPreferences();
  const { data: session } = useSession();
  const { showToast } = useToast();
  const [backgroundImage, setBackgroundImageState] = useState<
    string | undefined
  >(preferences?.viewPreferences?.backgroundImage);
  const [backgroundBlur, setBackgroundBlurState] = useState<number>(
    preferences?.viewPreferences?.backgroundBlur || 0
  );
  const [backgroundOpacity, setBackgroundOpacityState] = useState<number>(
    preferences?.viewPreferences?.backgroundOpacity || 100
  );
  const [mounted, setMounted] = useState(false);

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

  // Sync with preferences (only for authenticated users)
  useEffect(() => {
    // Only sync if user is authenticated
    if (
      session?.user?.id &&
      preferences?.viewPreferences?.backgroundImage !== backgroundImage
    ) {
      setBackgroundImageState(preferences?.viewPreferences?.backgroundImage);
    }
    if (preferences?.viewPreferences?.backgroundBlur !== backgroundBlur) {
      setBackgroundBlurState(preferences?.viewPreferences?.backgroundBlur || 0);
    }
    if (preferences?.viewPreferences?.backgroundOpacity !== backgroundOpacity) {
      setBackgroundOpacityState(
        preferences?.viewPreferences?.backgroundOpacity || 100
      );
    }
  }, [
    preferences?.viewPreferences?.backgroundImage,
    preferences?.viewPreferences?.backgroundBlur,
    preferences?.viewPreferences?.backgroundOpacity,
    backgroundImage,
    backgroundBlur,
    backgroundOpacity,
    session?.user?.id,
  ]);

  // Apply background image to document body
  useEffect(() => {
    if (mounted) {
      const body = document.body;

      // Supprimer l'ancien élément de fond s'il existe
      const existingBackground = document.getElementById('custom-background');
      if (existingBackground) {
        existingBackground.remove();
      }

      if (backgroundImage) {
        console.log('Creating background element for:', backgroundImage);
        // Créer un élément div pour l'image de fond avec les effets
        const backgroundElement = document.createElement('div');
        backgroundElement.id = 'custom-background';
        backgroundElement.style.position = 'fixed';
        backgroundElement.style.top = '0';
        backgroundElement.style.left = '0';
        backgroundElement.style.width = '100%';
        backgroundElement.style.height = '100%';
        backgroundElement.style.zIndex = '-1';
        backgroundElement.style.pointerEvents = 'none';

        // Vérifier si c'est une URL d'image ou un preset
        const presetIds = PRESET_BACKGROUNDS.map((preset) => preset.id);

        if (
          backgroundImage &&
          presetIds.includes(backgroundImage as (typeof presetIds)[number])
        ) {
          // Trouver le preset correspondant
          const preset = PRESET_BACKGROUNDS.find(
            (p) => p.id === backgroundImage
          );
          if (preset) {
            // Appliquer le gradient directement
            backgroundElement.style.background = preset.preview;
            // Ajouter une classe pour identifier le type de background
            backgroundElement.className = `preset-background preset-${preset.id}`;
          }
        } else {
          // Appliquer l'URL d'image personnalisée
          backgroundElement.style.backgroundImage = `url(${backgroundImage})`;
          backgroundElement.className = 'custom-background';
        }

        // Appliquer les propriétés communes
        backgroundElement.style.backgroundSize = 'cover';
        backgroundElement.style.backgroundPosition = 'center';
        backgroundElement.style.backgroundRepeat = 'no-repeat';
        backgroundElement.style.filter = `blur(${backgroundBlur}px)`;
        backgroundElement.style.opacity = `${backgroundOpacity / 100}`;

        // Ajouter l'élément au body
        body.appendChild(backgroundElement);
        body.classList.add('has-background-image');
      } else {
        // Supprimer l'image de fond
        body.classList.remove('has-background-image');
      }
    }
  }, [backgroundImage, backgroundBlur, backgroundOpacity, mounted]);

  const setBackgroundImage = (image: string | undefined) => {
    setBackgroundImageState(image);
  };

  const cycleBackground = () => {
    const currentBackground = backgroundImage; // Utiliser le state local au lieu des préférences
    const customImages = preferences?.viewPreferences?.customImages || [];

    const nextBackground = getNextBackground(
      currentBackground || 'none',
      customImages
    );
    const newBackgroundImage =
      nextBackground === 'none' ? undefined : nextBackground;

    setBackgroundImageState(newBackgroundImage);

    // Sauvegarder seulement si l'utilisateur est authentifié
    if (session?.user?.id) {
      updateViewPreferences({ backgroundImage: newBackgroundImage });
    }

    // Afficher le toast avec le nom du background
    const backgroundName =
      BACKGROUND_NAMES[nextBackground] || 'Image personnalisée';
    showToast(`Background: ${backgroundName}`, 2000, TOAST_ICONS.background);
  };

  return (
    <BackgroundContext.Provider
      value={{ backgroundImage, setBackgroundImage, cycleBackground }}
    >
      {children}
    </BackgroundContext.Provider>
  );
}

export function useBackground() {
  const context = useContext(BackgroundContext);
  if (context === undefined) {
    throw new Error('useBackground must be used within a BackgroundProvider');
  }
  return context;
}
