import {
  createContext,
  createEffect,
  createSignal,
  ParentComponent,
  useContext,
} from "solid-js";

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

const STORAGE_KEY = "bookra-theme";

function getInitialTheme(): Theme {
  if (typeof window === "undefined") return "system";
  const stored = localStorage.getItem(STORAGE_KEY) as Theme | null;
  return stored ?? "system";
}

function getResolvedTheme(theme: Theme): "light" | "dark" {
  if (theme === "system") {
    return window.matchMedia("(prefers-color-scheme: dark)").matches
      ? "dark"
      : "light";
  }
  return theme;
}

type ThemeContextValue = {
  theme: () => Theme;
  resolvedTheme: () => "light" | "dark";
  setTheme: (theme: Theme) => void;
  toggle: () => void;
};

const ThemeContext = createContext<ThemeContextValue>();

export const ThemeProvider: ParentComponent = (props) => {
  const [theme, setThemeSignal] = createSignal<Theme>(getInitialTheme());
  const [resolvedTheme, setResolvedTheme] = createSignal<"light" | "dark">(
    getResolvedTheme(getInitialTheme())
  );

  const applyTheme = (t: Theme) => {
    const resolved = getResolvedTheme(t);
    setResolvedTheme(resolved);

    const root = document.documentElement;
    root.classList.remove("light", "dark");
    root.classList.add(resolved);
    root.setAttribute("data-theme", resolved);
  };

  createEffect(() => {
    const t = theme();
    localStorage.setItem(STORAGE_KEY, t);
    applyTheme(t);
  });

  if (typeof window !== "undefined") {
    const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
    mediaQuery.addEventListener("change", () => {
      if (theme() === "system") {
        applyTheme("system");
      }
    });
  }

  const setTheme = (t: Theme) => setThemeSignal(t);

  const toggle = () => {
    const current = resolvedTheme();
    setTheme(current === "light" ? "dark" : "light");
  };

  return (
    <ThemeContext.Provider value={{ theme, resolvedTheme, setTheme, toggle }}>
      {props.children}
    </ThemeContext.Provider>
  );
};

export function useTheme() {
  const context = useContext(ThemeContext);
  if (!context) {
    throw new Error("ThemeProvider is missing from the component tree.");
  }
  return context;
}
