import React, {
  createContext,
  useContext,
  useEffect,
  useState,
  type ReactNode,
} from "react";

export type ThemeName =
  | "light"
  | "dark"
  | "sepia"
  | "noir"
  | "ocean"
  | "forest"
  | "gruvbox";

export interface ThemeColors {
  primary: string;
  primaryHover: string;
  secondary: string;
  background: string;
  surface: string;
  surfaceHover: string;
  text: string;
  textSecondary: string;
  textMuted: string;
  border: string;
  borderLight: string;
  success: string;
  warning: string;
  error: string;
  info: string;
  link: string;
  linkHover: string;
  shadow: string;
  overlay: string;
}

export interface Theme {
  name: ThemeName;
  colors: ThemeColors;
}

const themes: Record<ThemeName, Theme> = {
  light: {
    name: "light",
    colors: {
      primary: "#543fd7",
      primaryHover: "#4532b8",
      secondary: "#f39c12",
      background: "#ffffff",
      surface: "#f8f9fa",
      surfaceHover: "#e9ecef",
      text: "#212529",
      textSecondary: "#495057",
      textMuted: "#6c757d",
      border: "#dee2e6",
      borderLight: "#e9ecef",
      success: "#28a745",
      warning: "#ffc107",
      error: "#dc3545",
      info: "#17a2b8",
      link: "#543fd7",
      linkHover: "#4532b8",
      shadow: "rgba(0, 0, 0, 0.1)",
      overlay: "rgba(0, 0, 0, 0.5)",
    },
  },
  dark: {
    name: "dark",
    colors: {
      primary: "#7c6ef7",
      primaryHover: "#9085f9",
      secondary: "#f39c12",
      background: "#0d1117",
      surface: "#161b22",
      surfaceHover: "#21262d",
      text: "#c9d1d9",
      textSecondary: "#8b949e",
      textMuted: "#6e7681",
      border: "#30363d",
      borderLight: "#21262d",
      success: "#3fb950",
      warning: "#d29922",
      error: "#f85149",
      info: "#58a6ff",
      link: "#58a6ff",
      linkHover: "#79b8ff",
      shadow: "rgba(0, 0, 0, 0.3)",
      overlay: "rgba(0, 0, 0, 0.7)",
    },
  },
  sepia: {
    name: "sepia",
    colors: {
      primary: "#8b4513",
      primaryHover: "#6b3410",
      secondary: "#d2691e",
      background: "#f4e8d0",
      surface: "#ede0c8",
      surfaceHover: "#e6d9c0",
      text: "#3e2723",
      textSecondary: "#5d4037",
      textMuted: "#6d4c41",
      border: "#d7ccc8",
      borderLight: "#e0d5d0",
      success: "#689f38",
      warning: "#ff9800",
      error: "#d32f2f",
      info: "#0288d1",
      link: "#8b4513",
      linkHover: "#6b3410",
      shadow: "rgba(62, 39, 35, 0.1)",
      overlay: "rgba(62, 39, 35, 0.5)",
    },
  },
  noir: {
    name: "noir",
    colors: {
      primary: "#ffffff",
      primaryHover: "#e0e0e0",
      secondary: "#808080",
      background: "#000000",
      surface: "#0a0a0a",
      surfaceHover: "#1a1a1a",
      text: "#ffffff",
      textSecondary: "#b0b0b0",
      textMuted: "#808080",
      border: "#333333",
      borderLight: "#1a1a1a",
      success: "#4caf50",
      warning: "#ff9800",
      error: "#f44336",
      info: "#2196f3",
      link: "#b0b0b0",
      linkHover: "#ffffff",
      shadow: "rgba(255, 255, 255, 0.1)",
      overlay: "rgba(0, 0, 0, 0.9)",
    },
  },
  ocean: {
    name: "ocean",
    colors: {
      primary: "#006994",
      primaryHover: "#005577",
      secondary: "#00acc1",
      background: "#e1f5fe",
      surface: "#b3e5fc",
      surfaceHover: "#81d4fa",
      text: "#01579b",
      textSecondary: "#0277bd",
      textMuted: "#4fc3f7",
      border: "#81d4fa",
      borderLight: "#b3e5fc",
      success: "#00c853",
      warning: "#ffab00",
      error: "#d50000",
      info: "#00b0ff",
      link: "#0277bd",
      linkHover: "#01579b",
      shadow: "rgba(1, 87, 155, 0.1)",
      overlay: "rgba(1, 87, 155, 0.5)",
    },
  },
  forest: {
    name: "forest",
    colors: {
      primary: "#2e7d32",
      primaryHover: "#1b5e20",
      secondary: "#689f38",
      background: "#f1f8e9",
      surface: "#dcedc8",
      surfaceHover: "#c5e1a5",
      text: "#1b5e20",
      textSecondary: "#33691e",
      textMuted: "#558b2f",
      border: "#aed581",
      borderLight: "#c5e1a5",
      success: "#4caf50",
      warning: "#ff9800",
      error: "#f44336",
      info: "#03a9f4",
      link: "#388e3c",
      linkHover: "#2e7d32",
      shadow: "rgba(27, 94, 32, 0.1)",
      overlay: "rgba(27, 94, 32, 0.5)",
    },
  },
  gruvbox: {
    name: "gruvbox",
    colors: {
      primary: "#fe8019",
      primaryHover: "#d65d0e",
      secondary: "#fabd2f",
      background: "#282828",
      surface: "#3c3836",
      surfaceHover: "#504945",
      text: "#ebdbb2",
      textSecondary: "#d5c4a1",
      textMuted: "#bdae93",
      border: "#665c54",
      borderLight: "#504945",
      success: "#b8bb26",
      warning: "#fabd2f",
      error: "#fb4934",
      info: "#83a598",
      link: "#8ec07c",
      linkHover: "#b8bb26",
      shadow: "rgba(0, 0, 0, 0.3)",
      overlay: "rgba(40, 40, 40, 0.8)",
    },
  },
};

interface ThemeContextType {
  theme: Theme;
  themeName: ThemeName;
  setTheme: (name: ThemeName) => void;
  availableThemes: ThemeName[];
}

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

interface ThemeProviderProps {
  children: ReactNode;
  defaultTheme?: ThemeName;
}

export const ThemeProvider: React.FC<ThemeProviderProps> = ({
  children,
  defaultTheme = "light",
}) => {
  const [themeName, setThemeName] = useState<ThemeName>(() => {
    const savedTheme = localStorage.getItem("theme") as ThemeName;
    if (savedTheme && themes[savedTheme]) {
      return savedTheme;
    }

    if (
      window.matchMedia &&
      window.matchMedia("(prefers-color-scheme: dark)").matches
    ) {
      return "dark";
    }

    return defaultTheme;
  });

  const theme = themes[themeName];

  useEffect(() => {
    const root = document.documentElement;

    root.setAttribute("data-theme", themeName);

    Object.entries(theme.colors).forEach(([key, value]) => {
      const cssVarName = `--color-${key.replace(/([A-Z])/g, "-$1").toLowerCase()}`;
      root.style.setProperty(cssVarName, value);
    });

    localStorage.setItem("theme", themeName);
  }, [themeName, theme]);

  useEffect(() => {
    const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
    const handleChange = (e: MediaQueryListEvent) => {
      const savedTheme = localStorage.getItem("theme");
      if (!savedTheme) {
        setThemeName(e.matches ? "dark" : "light");
      }
    };

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

  const setTheme = (name: ThemeName) => {
    if (themes[name]) {
      setThemeName(name);
    }
  };

  const value: ThemeContextType = {
    theme,
    themeName,
    setTheme,
    availableThemes: Object.keys(themes) as ThemeName[],
  };

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

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