import AsyncStorage from "@react-native-async-storage/async-storage";
import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
  type ReactNode,
} from "react";
import { useColorScheme as useSystemColorScheme, type ColorSchemeName } from "react-native";

import { getThemeColors, type ThemeColors } from "@/lib/theme-palette";

export type ColorMode = "system" | "light" | "dark";

const STORAGE_KEY = "beenvoice:color-mode";

type ThemeContextValue = {
  colorMode: ColorMode;
  setColorMode: (mode: ColorMode) => Promise<void>;
  colorScheme: NonNullable<ColorSchemeName>;
  colors: ThemeColors;
  isDark: boolean;
};

const ThemeContext = createContext<ThemeContextValue | null>(null);

export function ThemeProvider({ children }: { children: ReactNode }) {
  const systemScheme = useSystemColorScheme();
  const [colorMode, setColorModeState] = useState<ColorMode>("system");
  const [ready, setReady] = useState(false);

  useEffect(() => {
    AsyncStorage.getItem(STORAGE_KEY)
      .then((stored) => {
        if (stored === "light" || stored === "dark" || stored === "system") {
          setColorModeState(stored);
        }
      })
      .finally(() => setReady(true));
  }, []);

  const colorScheme: NonNullable<ColorSchemeName> =
    colorMode === "system" ? (systemScheme ?? "light") : colorMode;

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

  const setColorMode = useCallback(async (mode: ColorMode) => {
    setColorModeState(mode);
    await AsyncStorage.setItem(STORAGE_KEY, mode);
  }, []);

  const value = useMemo(
    () => ({
      colorMode,
      setColorMode,
      colorScheme,
      colors,
      isDark: colorScheme === "dark",
    }),
    [colorMode, setColorMode, colorScheme, colors],
  );

  if (!ready) {
    return (
      <ThemeContext.Provider
        value={{
          colorMode: "system",
          setColorMode: async () => {},
          colorScheme: systemScheme ?? "light",
          colors: getThemeColors(systemScheme ?? "light"),
          isDark: systemScheme === "dark",
        }}
      >
        {children}
      </ThemeContext.Provider>
    );
  }

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

export function useAppTheme() {
  const ctx = useContext(ThemeContext);
  if (!ctx) throw new Error("useAppTheme must be used within ThemeProvider");
  return ctx;
}
