"use client";

import { useEffect, useRef, useState } from "react";
import { Moon, Sun } from "lucide-react";
import { useTheme } from "next-themes";

const SWITCH_MS = 360;

export function ThemeToggle() {
  const { resolvedTheme, setTheme } = useTheme();
  const [mounted, setMounted] = useState(false);
  const [animating, setAnimating] = useState(false);
  const frameRef = useRef<number | null>(null);
  const timerRef = useRef<number | null>(null);
  const switchingRef = useRef(false);

  useEffect(() => {
    setMounted(true);

    return () => {
      if (frameRef.current !== null) {
        window.cancelAnimationFrame(frameRef.current);
      }

      if (timerRef.current !== null) {
        window.clearTimeout(timerRef.current);
      }

      switchingRef.current = false;
      document.documentElement.classList.remove("theme-switching");
    };
  }, []);

  if (!mounted) {
    return <div className="h-8 w-8" aria-hidden="true" />;
  }

  const isDark = resolvedTheme === "dark";

  const toggleTheme = () => {
    if (animating || switchingRef.current || typeof window === "undefined") return;

    const root = document.documentElement;
    const nextTheme = isDark ? "light" : "dark";
    switchingRef.current = true;
    setAnimating(true);

    if (frameRef.current !== null) {
      window.cancelAnimationFrame(frameRef.current);
    }

    if (timerRef.current !== null) {
      window.clearTimeout(timerRef.current);
    }

    root.classList.add("theme-switching");
    // Let the browser apply transition styles before next-themes flips the dark class.
    void root.offsetWidth;

    frameRef.current = window.requestAnimationFrame(() => {
      frameRef.current = null;
      setTheme(nextTheme);

      timerRef.current = window.setTimeout(() => {
        timerRef.current = null;
        switchingRef.current = false;
        root.classList.remove("theme-switching");
        setAnimating(false);
      }, SWITCH_MS);
    });
  };

  return (
    <button
      type="button"
      onClick={toggleTheme}
      disabled={animating}
      className="relative grid h-8 w-8 place-items-center overflow-hidden rounded-lg text-slate-400 transition-colors duration-300 ease-out hover:bg-slate-100 hover:text-slate-600 disabled:pointer-events-none dark:hover:bg-slate-800 dark:hover:text-slate-200"
      title="切换亮色/暗色模式"
      aria-label="切换亮色/暗色模式"
    >
      <span className="absolute inset-0 rounded-lg bg-current opacity-0 transition-opacity hover:opacity-5" />
      <Sun className="absolute h-4 w-4 scale-100 rotate-0 opacity-100 transition-all duration-300 dark:scale-0 dark:-rotate-90 dark:opacity-0" />
      <Moon className="absolute h-4 w-4 scale-0 rotate-90 opacity-0 transition-all duration-300 dark:scale-100 dark:rotate-0 dark:opacity-100" />
    </button>
  );
}
