import { createContext, useContext, useEffect } from "react";

import usePluginSettings from "./settings";

type Theme = "dark" | "light" | "system";

interface ThemeProviderProps {
  children: React.ReactNode;
}

interface ThemeProviderState {
  theme: Theme;
  setTheme: (theme: Theme) => void;
}

const initialState: ThemeProviderState = {
  theme: "system",
  setTheme: () => null,
};

const ThemeProviderContext = createContext<ThemeProviderState>(initialState);

export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
  const { settings, setSettings } = usePluginSettings();
  const theme = settings.theme;

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

    const updateIcon = (useDarkModeIcons: boolean) => {
      const iconSuffix = useDarkModeIcons ? "-darkmode.png" : ".png";

      const iconPaths = {
        "16": `logo-16${iconSuffix}`,
        "48": `logo-48${iconSuffix}`,
        "128": `logo-128${iconSuffix}`,
      };
      chrome.action.setIcon({ path: iconPaths });
    };

    const applyThemeAndIcon = () => {
      root.classList.remove("light", "dark");

      let currentTheme: "light" | "dark";
      if (theme === "system") {
        currentTheme = window.matchMedia("(prefers-color-scheme: dark)").matches
          ? "dark"
          : "light";
      } else {
        currentTheme = theme;
      }

      root.classList.add(currentTheme);
      updateIcon(currentTheme === "dark");
    };

    applyThemeAndIcon();
  }, [theme]);

  const value = {
    theme,
    setTheme: (newTheme: Theme) => {
      setSettings((s) => ({ ...s, theme: newTheme }));
    },
  };

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

export const useTheme = () => {
  const context = useContext(ThemeProviderContext);

  if (context === undefined)
    throw new Error("useTheme must be used within a ThemeProvider");

  return context;
};
