import { ThemeContext } from "@/contexts/ThemeContext";
import { ThemeMode, AccentTheme } from "@/types/theme.interface";
import { useState, useEffect, useCallback, useMemo } from "react";

const STORAGE_KEYS = {
  mode: "techzaa-mode",
  accent: "techzaa-accent",
} as const;

const isValidMode = (value: unknown): value is ThemeMode =>
  value === "light" || value === "dark";

const isValidAccent = (value: unknown): value is AccentTheme =>
  value === "blue" || value === "purple" || value === "green";

export function ThemeProvider({ children }: { children: React.ReactNode }) {
  const [mode, setMode] = useState<ThemeMode>(() => {
    if (typeof window === "undefined") return "dark";

    const stored = localStorage.getItem(STORAGE_KEYS.mode);

    return isValidMode(stored) ? stored : "dark";
  });

  const [accent, setAccent] = useState<AccentTheme>(() => {
    if (typeof window === "undefined") return "blue";

    const stored = localStorage.getItem(STORAGE_KEYS.accent);

    return isValidAccent(stored) ? stored : "blue";
  });

  useEffect(() => {
    if (typeof document === "undefined") return;

    const root = document.documentElement;

    root.classList.remove("light", "dark");
    root.classList.add(mode);

    root.classList.remove("theme-blue", "theme-purple", "theme-green");
    root.classList.add(`theme-${accent}`);

    localStorage.setItem(STORAGE_KEYS.mode, mode);
    localStorage.setItem(STORAGE_KEYS.accent, accent);
  }, [mode, accent]);

  const toggleMode = useCallback(() => {
    setMode((prev) => (prev === "dark" ? "light" : "dark"));
  }, []);

  const value = useMemo(
    () => ({
      mode,
      accent,
      setMode,
      setAccent,
      toggleMode,
    }),
    [mode, accent, toggleMode],
  );

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