import { useEffect, useState } from "preact/hooks";
import { getConfiguredToken, setAuthToken, verifySession } from "@/lib/api";

const TOKEN_STORAGE_KEY = "sybil_admin_token";

export type AuthMode = "open" | "token";

function readStoredToken() {
  return localStorage.getItem(TOKEN_STORAGE_KEY)?.trim() || null;
}

function persistToken(token: string | null) {
  if (token) {
    localStorage.setItem(TOKEN_STORAGE_KEY, token);
    return;
  }
  localStorage.removeItem(TOKEN_STORAGE_KEY);
}

function normalizeAuthError(message: string) {
  if (message.includes("missing bearer token") || message.includes("invalid bearer token")) {
    return "Authentication failed. Enter the ADMIN_TOKEN configured in server/.env.";
  }
  return message;
}

export function useSessionAuth() {
  const initialToken = readStoredToken() ?? getConfiguredToken() ?? "";

  const [authTokenInput, setAuthTokenInput] = useState(initialToken);
  const [isCheckingSession, setIsCheckingSession] = useState(true);
  const [isSigningIn, setIsSigningIn] = useState(false);
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  const [authMode, setAuthMode] = useState<AuthMode | null>(null);
  const [authError, setAuthError] = useState<string | null>(null);

  const completeSessionCheck = async (tokenCandidate: string | null) => {
    setAuthToken(tokenCandidate);
    const session = await verifySession();
    setIsAuthenticated(true);
    setAuthMode(session.mode);
    setAuthError(null);
    persistToken(tokenCandidate);
  };

  const handleAuthFailure = (message: string) => {
    setIsAuthenticated(false);
    setAuthMode(null);
    setAuthError(normalizeAuthError(message));
    setAuthToken(null);
    persistToken(null);
  };

  const handleSignIn = async (tokenCandidate: string | null) => {
    setIsSigningIn(true);
    setAuthError(null);
    try {
      await completeSessionCheck(tokenCandidate);
    } catch (err) {
      const message = err instanceof Error ? err.message : String(err);
      setAuthError(normalizeAuthError(message));
      setIsAuthenticated(false);
      setAuthMode(null);
    } finally {
      setIsSigningIn(false);
    }
  };

  const logout = () => {
    setAuthToken(null);
    persistToken(null);
    setIsAuthenticated(false);
    setAuthMode(null);
    setAuthError(null);
  };

  useEffect(() => {
    const token = readStoredToken() ?? getConfiguredToken();
    void (async () => {
      try {
        await completeSessionCheck(token);
      } catch (err) {
        const message = err instanceof Error ? err.message : String(err);
        handleAuthFailure(message);
      } finally {
        setIsCheckingSession(false);
      }
    })();
  }, []);

  return {
    authTokenInput,
    setAuthTokenInput,
    isCheckingSession,
    isSigningIn,
    isAuthenticated,
    authMode,
    authError,
    handleAuthFailure,
    handleSignIn,
    logout,
  };
}
