import { createContext, useContext, useState, useEffect, ReactNode } from 'react';
import { API_BASE_URL, IS_WORDPRESS } from '../constants';
import { useAuth } from './AuthContext';

export type Theme = 'system' | 'light' | 'dark';

interface ThemeContextProps {
  theme: Theme;
  effectiveTheme: 'light' | 'dark';
  setTheme: (theme: Theme) => Promise<void>;
}

interface ThemeProviderProps {
  children: ReactNode;
}

const ThemeContext = createContext<ThemeContextProps | undefined>(undefined);
const PLUGIN_THEME_STORAGE_KEY = IS_WORDPRESS ? 'actionpanel_ai_theme_preference' : 'wpa_theme_preference';

const readCookieValue = (cookieName: string): string | null => {
  const cookies = document.cookie.split('; ');
  const matchingCookie = cookies.find(row => row.startsWith(`${cookieName}=`));
  return matchingCookie?.split('=')[1] ?? null;
};

const readPluginThemePreference = (): Theme | null => {
  try {
    const value = localStorage.getItem(PLUGIN_THEME_STORAGE_KEY);
    return value === 'system' || value === 'light' || value === 'dark' ? value : null;
  } catch {
    return null;
  }
};

const writePluginThemePreference = (theme: Theme) => {
  try {
    localStorage.setItem(PLUGIN_THEME_STORAGE_KEY, theme);
  } catch {
    // Ignore storage issues and continue with in-memory state.
  }
};

export const ThemeProvider = ({ children }: ThemeProviderProps): JSX.Element => {
  const { isLoggedIn, userInfo } = useAuth();
  const [prevLoggedIn, setPrevLoggedIn] = useState(isLoggedIn);
  
  // Initialize theme from cookie, default to dark if not logged in and no cookie
  const [theme, setThemeState] = useState<Theme>(() => {
    if (IS_WORDPRESS) {
      const savedTheme = readPluginThemePreference();
      if (savedTheme) {
        return savedTheme;
      }

      return 'dark';
    }

    const savedTheme = readCookieValue('wp-dark-mode-choice');
    
    // If user has a cookie preference, use it
    if (savedTheme === 'light' || savedTheme === 'dark') {
      return savedTheme;
    }
    
    // Default to dark mode when not logged in and no cookie preference
    return 'dark';
  });

  // Sync with user's theme when they log in
  useEffect(() => {
    if (isLoggedIn && userInfo?.theme) {
      // Only update if the themes are different
      if (theme !== userInfo.theme) {
        setThemeState(userInfo.theme);
        if (IS_WORDPRESS) {
          writePluginThemePreference(userInfo.theme);
        } else {
          document.cookie = `wp-dark-mode-choice=${userInfo.theme}; path=/;`;
        }
      }
    }
  }, [IS_WORDPRESS, isLoggedIn, theme, userInfo]);

  // Handle logout
  useEffect(() => {
    if (prevLoggedIn && !isLoggedIn) {
      // When logging out, set to dark mode instead of system preference
      if (IS_WORDPRESS) {
        writePluginThemePreference('dark');
      } else {
        document.cookie = `wp-dark-mode-choice=dark; path=/;`;
      }
      setThemeState('dark');
    }
    setPrevLoggedIn(isLoggedIn);
  }, [IS_WORDPRESS, isLoggedIn, prevLoggedIn]);

  const setTheme = async (newTheme: Theme) => {
    setThemeState(newTheme);
    if (IS_WORDPRESS) {
      writePluginThemePreference(newTheme);
    } else {
      // Store only light/dark in the wp cookie, use dark if theme is 'system'
      const cookieValue = newTheme === 'system'
        ? 'dark'  // Default to dark instead of system preference
        : newTheme;
      document.cookie = `wp-dark-mode-choice=${cookieValue}; path=/;`;
    }

    if (isLoggedIn) {
      try {
        const response = await fetch(`${API_BASE_URL}/account/theme`, {
          method: 'PUT',
          credentials: 'include',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ theme: newTheme }),
        });

        if (!response.ok) {
          const errorData = await response.json();
          throw new Error(errorData.detail || 'Failed to update theme');
        }
      } catch (error) {
        console.error('Error updating theme on server:', error);
      }
    }
  };

  const [effectiveTheme, setEffectiveTheme] = useState<'light' | 'dark'>(() => {
    if (theme === 'system') {
      // Default to dark theme instead of system preference
      return 'dark';
    }
    return theme as 'light' | 'dark';
  });

  // Handle system theme changes - but still default to dark when theme is 'system'
  useEffect(() => {
    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
    
    const handleChange = () => {
      if (theme === 'system') {
        // We're now ignoring system preference and always using dark mode for 'system'
        setEffectiveTheme('dark');
      }
    };

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

  // Update effective theme when theme changes
  useEffect(() => {
    if (theme === 'system') {
      // Default to dark theme instead of system preference
      setEffectiveTheme('dark');
    } else {
      setEffectiveTheme(theme as 'light' | 'dark');
    }
  }, [theme]);

  // Apply theme to document
  useEffect(() => {
    document.documentElement.classList.toggle('dark', effectiveTheme === 'dark');
    (window as any).actionPanelAiSetTheme?.(effectiveTheme);
  }, [effectiveTheme]);

  const value: ThemeContextProps = {
    theme,
    effectiveTheme,
    setTheme,
  };

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

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