"use client";

import { useEffect, useState } from "react";
import Link from "next/link";

import { useT } from "@/hooks/i18n/useT";
import { TOTPInput } from "@/components/auth/TOTPInput";
import { Button } from "@/components/ui/button";
import { verifyMfa } from "@/app/actions/auth/verifyMfa";
import { AvisoSemResposta, useEnvioComTeto } from "@/components/auth/teto-da-espera";

interface MfaFormProps {
  next?: string;
}

export function MfaForm({ next }: MfaFormProps) {
  const t = useT();
  const [code, setCode] = useState("");
  const [confiar, setConfiar] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [locked, setLocked] = useState(false);
  const [secondsLeft, setSecondsLeft] = useState(0);
  const { pendente: isPending, semResposta, enviar } = useEnvioComTeto();

  useEffect(() => {
    if (!locked || secondsLeft <= 0) return;
    const t = setInterval(() => {
      setSecondsLeft((s) => {
        if (s <= 1) {
          setLocked(false);
          setError(null);
          return 0;
        }
        return s - 1;
      });
    }, 1000);
    return () => clearInterval(t);
  }, [locked, secondsLeft]);

  const submit = (codeArg?: string) => {
    const finalCode = codeArg ?? code;
    if (finalCode.length !== 6 || locked) return;
    setError(null);
    void enviar(() => verifyMfa(finalCode, next, confiar), (res) => {
      if (!res) return; // server-side redirect on success
      if (res.error === "mfa_locked") {
        setLocked(true);
        setSecondsLeft(res.retry_in_seconds ?? 60);
        setError(
          `${t("Muitas tentativas. Aguarde")} ${res.retry_in_seconds ?? 60}s ${t("e tente novamente.")}`,
        );
        setCode("");
      } else {
        setError(t("Código inválido. Tente novamente."));
        setCode("");
      }
    });
  };

  const recoveryHref = next
    ? `/login/recovery?next=${encodeURIComponent(next)}`
    : "/login/recovery";

  return (
    <form
      // Ver a nota nos outros formulários de autenticação: sem JavaScript o
      // submit nativo é GET, e o código de verificação iria para a query
      // string — histórico, log do servidor e Referer.
      method="post"
      onSubmit={(e) => {
        e.preventDefault();
        submit();
      }}
      className="space-y-6"
      noValidate
    >
      <TOTPInput
        value={code}
        onChange={setCode}
        onComplete={(c) => submit(c)}
        disabled={isPending || locked}
        autoFocus
        hasError={!!error}
      />

      <label className="flex cursor-pointer items-start gap-2 text-sm">
        <input
          type="checkbox"
          checked={confiar}
          onChange={(e) => setConfiar(e.target.checked)}
          className="mt-0.5 h-4 w-4 rounded-md border-border"
        />
        <span>{t("Confiar neste dispositivo por 30 dias")}</span>
      </label>

      {error && (
        <div
          role="alert"
          className="rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-center text-sm text-destructive"
        >
          {locked && secondsLeft > 0
            ? `${t("Muitas tentativas. Tente novamente em")} ${secondsLeft}s.`
            : error}
        </div>
      )}
      {semResposta && <AvisoSemResposta />}

      <Button
        type="submit"
        className="w-full"
        disabled={isPending || locked || code.length !== 6}
      >
        {isPending ? t("Verificando...") : t("Verificar")}
      </Button>

      <div className="text-center text-sm">
        <Link href={recoveryHref} className="text-muted-foreground underline-offset-4 hover:underline">
          {t("Perdi acesso ao autenticador")}
        </Link>
      </div>
    </form>
  );
}
