"use client";

import { useEffect, useRef, useState, useTransition } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import Link from "next/link";
import { CircleAlert, LoaderCircle, ShieldCheck } from "lucide-react";
import { Button } from "@/components/ui/button";
import { authDestination, postAuthRequest, type AuthRequestResult } from "./auth-client";
import { parseOtpLink } from "./otp-link-contract";

export function OtpLinkVerification({ apiEnabled, signedInEmail, signedInDestination = "/", sessionCheckFailed = false }: {
  apiEnabled: boolean;
  signedInEmail?: string;
  signedInDestination?: "/" | "/set-password";
  sessionCheckFailed?: boolean;
}) {
  const router = useRouter();
  const params = useSearchParams();
  const [link] = useState(() => parseOtpLink(new URLSearchParams(params.toString())));
  const [attempt, setAttempt] = useState(0);
  const [outcome, setOutcome] = useState<{ attempt: number; result: AuthRequestResult }>();
  const request = useRef<{ attempt: number; promise: Promise<AuthRequestResult> } | null>(null);
  const [signedOut, setSignedOut] = useState(false);
  const [signingOut, setSigningOut] = useState(false);
  const [logoutError, setLogoutError] = useState("");
  const [reviewing, startReview] = useTransition();
  const logoutPending = useRef(false);
  const activeEmail = signedOut ? undefined : signedInEmail;
  const differentAccount = Boolean(link && activeEmail && link.email.toLowerCase() !== activeEmail.toLowerCase());
  const canVerify = apiEnabled && !sessionCheckFailed && link !== null && !activeEmail;
  const result = outcome?.attempt === attempt ? outcome.result : undefined;
  const verifying = canVerify && !result;
  const success = result?.ok === true && Boolean(result.session);

  useEffect(() => {
    // Keep link credentials out of the address bar and back-navigation entry.
    window.history.replaceState(window.history.state, "", "/otp-verify");
  }, []);

  useEffect(() => {
    if (!link || !apiEnabled || sessionCheckFailed || differentAccount || reviewing) return;
    if (activeEmail) {
      router.replace(signedInDestination);
      return;
    }
    // Strict Mode replays effects. Reuse the same request for this attempt.
    if (request.current?.attempt !== attempt) {
      request.current = { attempt, promise: postAuthRequest("/api/auth/verify-link", link) };
    }
    let active = true;
    void request.current.promise.then(response => {
      if (!active) return;
      setOutcome({ attempt, result: response });
      if (response.ok && response.session) {
        router.replace(authDestination(response.session));
        router.refresh();
      }
    });
    return () => { active = false; };
  }, [activeEmail, apiEnabled, attempt, differentAccount, link, reviewing, router, sessionCheckFailed, signedInDestination]);

  async function signOutAndContinue() {
    if (logoutPending.current) return;
    logoutPending.current = true;
    setSigningOut(true);
    setLogoutError("");
    try {
      const response = await postAuthRequest("/api/auth/logout");
      if (!response.ok) {
        setLogoutError(response.error);
        return;
      }
      setAttempt(current => current + 1);
      setSignedOut(true);
    } finally {
      logoutPending.current = false;
      setSigningOut(false);
    }
  }

  const error = reviewing ? ""
    : !apiEnabled ? "The authentication service is not configured. Contact your administrator."
    : sessionCheckFailed ? "Your current session could not be checked. Refresh this page using the original email link, or return to sign in."
    : !link ? "This verification link is incomplete or invalid. Request a new code from Sign In."
    : activeEmail ? ""
    : result && !result.ok ? result.error
    : result?.ok && !result.session ? "The authentication service did not return a valid session. Please return to Sign In."
    : "";
  const openingExistingSession = Boolean(link && activeEmail && !differentAccount && !error);
  const pending = reviewing || verifying || success || openingExistingSession;
  const Icon = error ? CircleAlert : pending ? LoaderCircle : ShieldCheck;

  return <div className="space-y-5">
    <span className={`flex size-12 items-center justify-center rounded-xl ${error ? "bg-destructive/10 text-destructive" : "bg-auth-action/10 text-auth-action"}`}><Icon aria-hidden="true" className={`size-6 ${pending ? "animate-spin motion-reduce:animate-none" : ""}`} /></span>
    <div className="space-y-2" role={error ? "alert" : "status"} aria-live="polite">
      <h1 className="text-2xl font-semibold sm:text-3xl">{reviewing ? "Checking current account" : error ? "Unable to verify link" : differentAccount ? "Switch account?" : success || openingExistingSession ? "Opening your dashboard" : "Verifying your sign-in link"}</h1>
      <p className="text-sm leading-relaxed text-auth-muted">{reviewing ? "Checking which account is signed in before continuing…" : error || (differentAccount ? `You are currently signed in as ${activeEmail}. This link is for ${link?.email}.` : success || openingExistingSession ? "You’re signed in. Redirecting you now…" : `Verifying the code for ${link?.email ?? "your account"}…`)}</p>
    </div>
    {differentAccount && !error && !reviewing && <>
      <p className="text-sm text-auth-muted">Sign out of the current account to continue with this email link.</p>
      {logoutError && <p role="alert" className="rounded-lg bg-destructive/10 p-3 text-sm text-destructive">{logoutError}</p>}
      <Button type="button" variant="auth" className="w-full" disabled={signingOut} onClick={signOutAndContinue}>{signingOut && <LoaderCircle aria-hidden="true" className="size-4 animate-spin motion-reduce:animate-none" />}{signingOut ? "Signing out…" : "Sign Out & Continue"}</Button>
      <Button asChild variant="outline" className="w-full"><Link href={signedInDestination} prefetch={false}>Keep Current Account</Link></Button>
    </>}
    {error && <div className="space-y-3">
      {result && !result.ok && result.status === 409 && <Button type="button" variant="auth" className="w-full" onClick={() => startReview(() => { setSignedOut(false); setAttempt(current => current + 1); router.refresh(); })}>Review Current Account</Button>}
      {canVerify && result && !result.ok && (result.status === 0 || result.status >= 500) && <Button type="button" variant="auth" className="w-full" onClick={() => setAttempt(attempt + 1)}>Retry Verification</Button>}
      <Button asChild variant="outline" className="w-full"><Link href="/signin" prefetch={false}>Back to Sign In</Link></Button>
    </div>}
    {success && result?.ok && result.session && <Button asChild variant="auth" className="w-full"><Link href={authDestination(result.session)} prefetch={false}>Continue to Dashboard</Link></Button>}
  </div>;
}
