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

const API_BASE = 'https://goonblog.thevakhovske.eu.org/api';

const ThemeContext = createContext();

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

export function ThemeProvider({ children }) {
  const [currentTheme, setCurrentTheme] = useState(null);
  const [allThemes, setAllThemes] = useState([]);
  const [activeThemeId, setActiveThemeId] = useState('default');
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  // Load themes on mount
  useEffect(() => {
    loadThemes();
  }, []);

  // Apply theme CSS variables when theme changes
  useEffect(() => {
    if (currentTheme) {
      applyThemeToCSS(currentTheme);
    }
  }, [currentTheme]);

  const loadThemes = async () => {
    try {
      setLoading(true);
      setError(null);
      
      console.log('Loading themes...');
      
      const response = await fetch(`${API_BASE}/themes`, {
        credentials: 'include',
      });
      console.log('Themes response status:', response.status, response.statusText);
      
      if (!response.ok) throw new Error('Failed to fetch themes');
      
      const data = await response.json();
      console.log('Themes data loaded:', data);
      
      setAllThemes(data.themes);
      setActiveThemeId(data.activeTheme);
      
      // Find and set current theme
      const activeTheme = data.themes.find(theme => theme.id === data.activeTheme);
      console.log('Looking for active theme:', data.activeTheme);
      console.log('Found active theme:', activeTheme);
      
      if (activeTheme) {
        setCurrentTheme(activeTheme);
        console.log('Applied theme:', activeTheme.name);
      } else {
        console.warn('Active theme not found, using default');
        const defaultTheme = data.themes.find(theme => theme.id === 'default');
        if (defaultTheme) {
          setCurrentTheme(defaultTheme);
        }
      }
    } catch (err) {
      console.error('Error loading themes:', err);
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };

  const setActiveTheme = async (themeId) => {
    try {
      setError(null);
      
      console.log('Setting active theme:', themeId);
      
      const response = await fetch(`${API_BASE}/themes/active`, {
        method: 'PUT',
        headers: {
          'Content-Type': 'application/json',
        },
        credentials: 'include',
        body: JSON.stringify({ themeId }),
      });

      console.log('Response status:', response.status, response.statusText);
      
      if (!response.ok) {
        let errorMessage = 'Failed to set active theme';
        try {
          const errorData = await response.json();
          errorMessage = errorData.error || errorMessage;
        } catch (e) {
          // If we can't parse error as JSON, use default message
        }
        throw new Error(`${errorMessage} (Status: ${response.status})`);
      }
      
      const data = await response.json();
      console.log('Theme set successfully:', data);
      
      setActiveThemeId(themeId);
      setCurrentTheme(data.theme);
      
      return { success: true };
    } catch (err) {
      console.error('Error setting active theme:', err);
      setError(err.message);
      return { success: false, error: err.message };
    }
  };

  const createTheme = async (themeData) => {
    try {
      setError(null);
      
      const response = await fetch(`${API_BASE}/themes`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        credentials: 'include',
        body: JSON.stringify(themeData),
      });

      if (!response.ok) {
        const errorData = await response.json();
        throw new Error(errorData.error || 'Failed to create theme');
      }
      
      const newTheme = await response.json();
      setAllThemes(prev => [...prev, newTheme]);
      
      return { success: true, theme: newTheme };
    } catch (err) {
      setError(err.message);
      return { success: false, error: err.message };
    }
  };

  const updateTheme = async (themeId, themeData) => {
    try {
      setError(null);
      
      const response = await fetch(`${API_BASE}/themes/${themeId}`, {
        method: 'PUT',
        headers: {
          'Content-Type': 'application/json',
        },
        credentials: 'include',
        body: JSON.stringify(themeData),
      });

      if (!response.ok) {
        const errorData = await response.json();
        throw new Error(errorData.error || 'Failed to update theme');
      }
      
      const updatedTheme = await response.json();
      
      // Update in themes list
      setAllThemes(prev => prev.map(theme => 
        theme.id === themeId ? updatedTheme : theme
      ));
      
      // Update current theme if it's the active one
      if (activeThemeId === themeId) {
        setCurrentTheme(updatedTheme);
      }
      
      return { success: true, theme: updatedTheme };
    } catch (err) {
      setError(err.message);
      return { success: false, error: err.message };
    }
  };

  const deleteTheme = async (themeId) => {
    try {
      setError(null);
      
      const response = await fetch(`${API_BASE}/themes/${themeId}`, {
        method: 'DELETE',
        credentials: 'include',
      });

      if (!response.ok) {
        const errorData = await response.json();
        throw new Error(errorData.error || 'Failed to delete theme');
      }
      
      // Remove from themes list
      setAllThemes(prev => prev.filter(theme => theme.id !== themeId));
      
      return { success: true };
    } catch (err) {
      setError(err.message);
      return { success: false, error: err.message };
    }
  };

  const exportTheme = async (themeId) => {
    try {
      const response = await fetch(`${API_BASE}/themes/${themeId}/export`, {
        credentials: 'include',
      });

      if (!response.ok) throw new Error('Failed to export theme');
      
      const themeData = await response.json();
      
      // Create and download file
      const blob = new Blob([JSON.stringify(themeData, null, 2)], { 
        type: 'application/json' 
      });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `theme-${themeId}.json`;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
      
      return { success: true };
    } catch (err) {
      setError(err.message);
      return { success: false, error: err.message };
    }
  };

  const importTheme = async (themeData) => {
    try {
      // Ensure unique ID
      const uniqueId = `${themeData.id}-${Date.now()}`;
      const importedTheme = {
        ...themeData,
        id: uniqueId,
        name: `${themeData.name} (Imported)`
      };
      
      return await createTheme(importedTheme);
    } catch (err) {
      setError(err.message);
      return { success: false, error: err.message };
    }
  };

  // Apply theme CSS variables to document root
  const applyThemeToCSS = (theme) => {
    if (!theme) {
      console.warn('No theme to apply');
      return;
    }
    
    console.log('Applying theme to CSS:', theme.name, theme.colors);
    
    const root = document.documentElement;
    
    // Apply color variables
    Object.entries(theme.colors).forEach(([key, value]) => {
      root.style.setProperty(`--color-${kebabCase(key)}`, value);
    });
    
    // Apply typography variables
    if (theme.typography) {
      root.style.setProperty('--font-family', theme.typography.fontFamily);
      root.style.setProperty('--font-family-heading', theme.typography.headingFontFamily);
      
      if (theme.typography.fontSize) {
        Object.entries(theme.typography.fontSize).forEach(([key, value]) => {
          root.style.setProperty(`--font-size-${key}`, value);
        });
      }
      
      if (theme.typography.lineHeight) {
        Object.entries(theme.typography.lineHeight).forEach(([key, value]) => {
          root.style.setProperty(`--line-height-${key}`, value);
        });
      }
    }
    
    // Apply layout variables
    if (theme.layout) {
      if (theme.layout.borderRadius) {
        Object.entries(theme.layout.borderRadius).forEach(([key, value]) => {
          root.style.setProperty(`--border-radius-${key}`, value);
        });
      }
      
      if (theme.layout.spacing) {
        Object.entries(theme.layout.spacing).forEach(([key, value]) => {
          root.style.setProperty(`--spacing-${key}`, value);
        });
      }
      
      if (theme.layout.shadows) {
        Object.entries(theme.layout.shadows).forEach(([key, value]) => {
          root.style.setProperty(`--shadow-${key}`, value);
        });
      }
    }
    
    // Apply custom CSS if present
    if (theme.customCSS) {
      let customStyleEl = document.getElementById('theme-custom-css');
      if (!customStyleEl) {
        customStyleEl = document.createElement('style');
        customStyleEl.id = 'theme-custom-css';
        document.head.appendChild(customStyleEl);
      }
      customStyleEl.textContent = theme.customCSS;
    }
  };

  // Helper function to convert camelCase to kebab-case
  const kebabCase = (str) => {
    return str.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`);
  };

  const value = {
    currentTheme,
    allThemes,
    activeThemeId,
    loading,
    error,
    loadThemes,
    setActiveTheme,
    createTheme,
    updateTheme,
    deleteTheme,
    exportTheme,
    importTheme
  };

  return (
    <ThemeContext.Provider value={value}>
      {children}
    </ThemeContext.Provider>
  );
}