"use client";

import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
} from "react";

interface AuthState {
  loading: boolean;
  authEnabled: boolean;
  loggedIn: boolean;
  username?: string;
  refresh: () => Promise<void>;
  logout: () => Promise<void>;
}

const AuthContext = createContext<AuthState | null>(null);

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const [loading, setLoading] = useState(true);
  const [authEnabled, setAuthEnabled] = useState(false);
  const [loggedIn, setLoggedIn] = useState(true);
  const [username, setUsername] = useState<string>();

  const refresh = useCallback(async () => {
    try {
      const res = await fetch("/api/auth/me", { cache: "no-store" });
      const data = await res.json();
      setAuthEnabled(!!data.authEnabled);
      setLoggedIn(!!data.loggedIn);
      setUsername(data.username);
    } catch {
      setAuthEnabled(false);
      setLoggedIn(true);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    refresh();
  }, [refresh]);

  const logout = useCallback(async () => {
    await fetch("/api/auth/logout", { method: "POST" });
    await refresh();
    window.location.href = "/";
  }, [refresh]);

  const value = useMemo(
    () => ({ loading, authEnabled, loggedIn, username, refresh, logout }),
    [loading, authEnabled, loggedIn, username, refresh, logout],
  );

  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}

export function useAuth() {
  const ctx = useContext(AuthContext);
  if (!ctx) {
    throw new Error("useAuth must be used within AuthProvider");
  }
  return ctx;
}

export function useRequireAuthForPath(path: string): boolean {
  const { authEnabled, loggedIn } = useAuth();
  if (!authEnabled) {
    return true;
  }
  const protectedPaths = ["/liuyao", "/bazi", "/combined", "/history"];
  if (!protectedPaths.some((p) => path === p || path.startsWith(`${p}/`))) {
    return true;
  }
  return loggedIn;
}
