import { createFileRoute, useNavigate, useRouter } from "@tanstack/react-router";
import { useState, type FormEvent } from "react";
import { z } from "zod";
import { AuthLayout } from "@/components/auth-layout";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
  InputOTP,
  InputOTPGroup,
  InputOTPSeparator,
  InputOTPSlot,
} from "@/components/ui/input-otp";
import { toast } from "sonner";
import { mfaVerifyFn } from "@/lib/auth/auth.functions";
import { useAuth } from "@/lib/auth/use-auth";

const searchSchema = z.object({ redirect: z.string().optional() });

export const Route = createFileRoute("/mfa")({
  validateSearch: searchSchema,
  head: () => ({ meta: [{ title: "Two-factor auth — VotersAlert" }] }),
  component: Page,
});

function Page() {
  const router = useRouter();
  const navigate = useNavigate();
  const { setUser, refresh } = useAuth();
  const { redirect } = Route.useSearch();
  const [code, setCode] = useState("");
  const [recovery, setRecovery] = useState("");
  const [useRecovery, setUseRecovery] = useState(false);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const onSubmit = async (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    const value = useRecovery ? recovery.trim() : code.trim();
    if (!value) {
      setError(useRecovery ? "Enter your recovery code." : "Enter the 6-digit code.");
      return;
    }
    setLoading(true);
    setError(null);
    try {
      const result = await mfaVerifyFn({
        data: { code: value, mode: useRecovery ? "recovery" : "totp" },
      });
      setUser(result.user as never);
      await refresh();
      await router.invalidate();
      toast.success("Verified");
      navigate({ to: redirect ?? result.redirectTo });
    } catch (err) {
      const message = err instanceof Error ? err.message : "Verification failed.";
      setError(message);
      toast.error(message);
    } finally {
      setLoading(false);
    }
  };

  return (
    <AuthLayout
      title="Two-factor verification"
      subtitle={
        useRecovery
          ? "Enter one of your saved recovery codes."
          : "Enter the 6-digit code from your authenticator app."
      }
      footer={
        <button
          type="button"
          onClick={() => {
            setUseRecovery((v) => !v);
            setError(null);
          }}
          className="text-primary font-medium hover:underline"
        >
          {useRecovery ? "Use authenticator code" : "Use backup code"}
        </button>
      }
    >
      <form onSubmit={onSubmit} className="space-y-5">
        {useRecovery ? (
          <Input
            value={recovery}
            onChange={(e) => setRecovery(e.target.value)}
            placeholder="XXXXX-XXXXX"
            autoComplete="one-time-code"
            className="text-center tracking-widest font-mono"
          />
        ) : (
          <div className="flex justify-center">
            <InputOTP maxLength={6} value={code} onChange={setCode}>
              <InputOTPGroup>
                <InputOTPSlot index={0} />
                <InputOTPSlot index={1} />
                <InputOTPSlot index={2} />
              </InputOTPGroup>
              <InputOTPSeparator />
              <InputOTPGroup>
                <InputOTPSlot index={3} />
                <InputOTPSlot index={4} />
                <InputOTPSlot index={5} />
              </InputOTPGroup>
            </InputOTP>
          </div>
        )}
        {error && (
          <div className="rounded-md border border-destructive/30 bg-destructive/5 px-3 py-2 text-xs text-destructive text-center">
            {error}
          </div>
        )}
        <Button type="submit" className="w-full h-10" disabled={loading}>
          {loading ? "Verifying…" : "Verify and continue"}
        </Button>
      </form>
    </AuthLayout>
  );
}
