/**
 * Theme Context Hook for managing app-wide theme state.
 * Supports Light, Dark, and System (automatic) modes across Expo platforms.
 *
 * IMPORTANT: Requires expo-system-ui plugin in app.json for Android status bar support.
 */

import { ColorName, Colors } from "@/constants/theme";
import { getStorageItem, setStorageItem } from "@/utils/storage";
import {
  createContext,
  ReactNode,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
} from "react";
import {
  Appearance,
  AppState,
  AppStateStatus,
  useColorScheme as useRNColorScheme,
} from "react-native";

export type ThemeMode = "light" | "dark" | "system";
export type ColorScheme = "light" | "dark";

interface ThemeContextType {
  themeMode: ThemeMode;
  colorScheme: ColorScheme;
  colors: typeof Colors.light;
  setThemeMode: (mode: ThemeMode) => Promise<void>;
  getColor: (colorName: ColorName) => string;
  isHydrated: boolean;
}

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

const THEME_STORAGE_KEY = "theme_mode";

const getSystemScheme = (): ColorScheme => {
  const scheme = Appearance.getColorScheme();
  // console.log("[Theme] Appearance.getColorScheme():", scheme);
  return scheme === "dark" ? "dark" : "light";
};

const isThemeMode = (value: unknown): value is ThemeMode => {
  return value === "light" || value === "dark" || value === "system";
};

export function ThemeProvider({ children }: { children: ReactNode }) {
  const [systemScheme, setSystemScheme] =
    useState<ColorScheme>(getSystemScheme);
  const [themeMode, setThemeModeState] = useState<ThemeMode>("system");
  const [isHydrated, setIsHydrated] = useState(false);

  const syncSystemScheme = useCallback(() => {
    const next = getSystemScheme();
    // console.log("[Theme] syncSystemScheme computed:", next);
    setSystemScheme((current) => (current === next ? current : next));
  }, []);

  const rnScheme = useRNColorScheme();
  useEffect(() => {
    if (!rnScheme) return;
    const next = rnScheme === "dark" ? "dark" : "light";
    // console.log("[Theme] useColorScheme hook emitted:", rnScheme);
    setSystemScheme((current) => (current === next ? current : next));
  }, [rnScheme]);

  useEffect(() => {
    const subscription = Appearance.addChangeListener(({ colorScheme }) => {
      const next = colorScheme === "dark" ? "dark" : "light";
      // console.log("[Theme] Appearance listener fired with:", colorScheme);
      setSystemScheme((current) => (current === next ? current : next));
    });

    syncSystemScheme();

    return () => {
      subscription.remove();
    };
  }, [syncSystemScheme]);

  useEffect(() => {
    // console.log("[Theme] System scheme detected:", systemScheme);
  }, [systemScheme]);

  useEffect(() => {
    const handleAppStateChange = (nextState: AppStateStatus) => {
      if (nextState === "active") {
        // console.log("[Theme] AppState active → scheduling system scheme sync");
        setTimeout(() => {
          // console.log("[Theme] AppState sync callback running");
          syncSystemScheme();
        }, 100);
      }
    };

    const subscription = AppState.addEventListener(
      "change",
      handleAppStateChange
    );
    return () => subscription.remove();
  }, [syncSystemScheme]);

  useEffect(() => {
    let isMounted = true;

    const hydrateThemeMode = async () => {
      try {
        const savedThemeMode = await getStorageItem(THEME_STORAGE_KEY);
        if (isMounted && isThemeMode(savedThemeMode)) {
          setThemeModeState(savedThemeMode);
        }
      } catch (error) {
        console.warn("[Theme] Failed to load theme mode:", error);
      } finally {
        if (isMounted) {
          setIsHydrated(true);
        }
      }
    };

    hydrateThemeMode();

    return () => {
      isMounted = false;
    };
  }, []);

  const colorScheme: ColorScheme =
    themeMode === "system" ? systemScheme : themeMode;

  const colors = useMemo(() => Colors[colorScheme], [colorScheme]);

  const setThemeMode = useCallback(async (mode: ThemeMode) => {
    setThemeModeState(mode);
    try {
      await setStorageItem(THEME_STORAGE_KEY, mode);
    } catch (error) {
      console.warn("[Theme] Failed to save theme mode:", error);
    }
  }, []);

  useEffect(() => {
    // console.log("[Theme] window defined:", typeof window !== "undefined");
  }, []);

  const getColor = useCallback(
    (colorName: ColorName) => colors[colorName] ?? colors.text,
    [colors]
  );

  useEffect(() => {
    // console.log("[Theme] Mode:", themeMode);
  }, [themeMode]);

  useEffect(() => {
    // console.log("[Theme] Derived colorScheme:", colorScheme);
  }, [colorScheme]);

  const value = useMemo(
    () => ({
      themeMode,
      colorScheme,
      colors,
      setThemeMode,
      getColor,
      isHydrated,
    }),
    [themeMode, colorScheme, colors, setThemeMode, getColor, isHydrated]
  );

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

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

export const useThemeContext = useTheme;

export function useColorScheme(): ColorScheme {
  return useTheme().colorScheme;
}
