import { useEffect, useState } from "react";

export type EffectiveTheme = "dark" | "light";
export type ThemePreference = "dark" | "light" | "system";

export const THEME_PREFERENCE_STORAGE_KEY = "dial.theme.preference";
export const THEME_MEDIA_QUERY = "(prefers-color-scheme: dark)";

export function applyInitialThemePreference() {
  applyThemeMode(resolveEffectiveTheme(readThemePreference(), getSystemPrefersDark()));
}

export function applyThemeMode(theme: EffectiveTheme, root: HTMLElement = document.documentElement) {
  root.setAttribute("theme-mode", theme);
}

export function getSystemPrefersDark(matchMedia: Window["matchMedia"] = window.matchMedia): boolean {
  try {
    return matchMedia(THEME_MEDIA_QUERY).matches;
  } catch {
    return false;
  }
}

export function parseThemePreference(value: unknown): ThemePreference {
  return value === "dark" || value === "light" || value === "system" ? value : "system";
}

export function readThemePreference(storage: Storage = window.localStorage): ThemePreference {
  try {
    return parseThemePreference(storage.getItem(THEME_PREFERENCE_STORAGE_KEY));
  } catch {
    return "system";
  }
}

export function resolveEffectiveTheme(preference: ThemePreference, systemPrefersDark: boolean): EffectiveTheme {
  if (preference === "dark" || preference === "light") return preference;
  return systemPrefersDark ? "dark" : "light";
}

export function useThemePreference() {
  const [preference, setPreferenceState] = useState<ThemePreference>(() => readThemePreference());
  const [systemPrefersDark, setSystemPrefersDark] = useState(() => getSystemPrefersDark());
  const effectiveTheme = resolveEffectiveTheme(preference, systemPrefersDark);

  useEffect(() => {
    applyThemeMode(effectiveTheme);
  }, [effectiveTheme]);

  useEffect(() => {
    const mediaQueryList = window.matchMedia(THEME_MEDIA_QUERY);

    const handleChange = (event: MediaQueryListEvent) => setSystemPrefersDark(event.matches);
    mediaQueryList.addEventListener("change", handleChange);
    return () => mediaQueryList.removeEventListener("change", handleChange);
  }, []);

  const setPreference = (nextPreference: ThemePreference) => {
    setPreferenceState(nextPreference);
    writeThemePreference(nextPreference);
  };

  return { effectiveTheme, preference, setPreference };
}

export function writeThemePreference(preference: ThemePreference, storage: Storage = window.localStorage) {
  try {
    storage.setItem(THEME_PREFERENCE_STORAGE_KEY, preference);
  } catch {
    // 存储不可用时仅使用当前内存状态，避免阻断 Dashboard 渲染。
  }
}
