"use client";

import { useState } from "react";
import QRCode from "qrcode";
import { toast } from "sonner";
import { useTranslations } from "next-intl";
import { ShieldCheck, ShieldOff, Copy, Check } from "lucide-react";
import { authClient } from "@/lib/auth/client";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from "@/components/ui/dialog";

type Step = "closed" | "password" | "setup" | "disable-password";

export function TwoFactorSettings({ initialEnabled, hasPassword }: { initialEnabled: boolean; hasPassword: boolean }) {
  const t = useTranslations("settingsForm");
  const [enabled, setEnabled] = useState(initialEnabled);
  const [step, setStep] = useState<Step>("closed");
  const [password, setPassword] = useState("");
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const [qrDataUrl, setQrDataUrl] = useState<string | null>(null);
  const [backupCodes, setBackupCodes] = useState<string[]>([]);
  const [confirmCode, setConfirmCode] = useState("");
  const [copied, setCopied] = useState(false);

  function closeAndReset() {
    setStep("closed");
    setPassword("");
    setError(null);
    setQrDataUrl(null);
    setBackupCodes([]);
    setConfirmCode("");
    setCopied(false);
  }

  async function startEnable() {
    setError(null);
    setBusy(true);
    try {
      const { data, error } = await authClient.twoFactor.enable(
        hasPassword ? { password } : {}
      );
      if (error || !data) {
        setError(error?.message ?? t("twoFactorEnableFailed"));
        return;
      }
      const dataUrl = await QRCode.toDataURL(data.totpURI, { margin: 1, width: 200 });
      setQrDataUrl(dataUrl);
      setBackupCodes(data.backupCodes);
      setStep("setup");
    } finally {
      setBusy(false);
    }
  }

  async function confirmEnable() {
    setError(null);
    setBusy(true);
    try {
      const { error } = await authClient.twoFactor.verifyTotp({ code: confirmCode.trim() });
      if (error) {
        setError(error.message ?? t("twoFactorInvalidCode"));
        return;
      }
      setEnabled(true);
      toast.success(t("twoFactorEnabled"));
      closeAndReset();
    } finally {
      setBusy(false);
    }
  }

  async function handleDisable() {
    setError(null);
    setBusy(true);
    try {
      const { error } = await authClient.twoFactor.disable(hasPassword ? { password } : {});
      if (error) {
        setError(error.message ?? t("twoFactorDisableFailed"));
        return;
      }
      setEnabled(false);
      toast.success(t("twoFactorDisabled"));
      closeAndReset();
    } finally {
      setBusy(false);
    }
  }

  async function copyBackupCodes() {
    try {
      await navigator.clipboard.writeText(backupCodes.join("\n"));
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    } catch {
      toast.error(t("twoFactorCopyFailed"));
    }
  }

  return (
    <section className="rounded-xl border p-6 space-y-4">
      <div className="flex items-center justify-between gap-3">
        <div>
          <h2 className="font-semibold text-lg">{t("twoFactorTitle")}</h2>
          <p className="text-sm text-muted-foreground mt-1 max-w-prose">{t("twoFactorDescription")}</p>
        </div>
        {enabled ? (
          <Button
            variant="outline"
            size="sm"
            onClick={() => setStep("disable-password")}
            className="gap-1.5 shrink-0"
          >
            <ShieldOff className="h-4 w-4" />
            {t("twoFactorDisableButton")}
          </Button>
        ) : (
          <Button
            size="sm"
            onClick={() => (hasPassword ? setStep("password") : void startEnable())}
            className="gap-1.5 shrink-0"
          >
            <ShieldCheck className="h-4 w-4" />
            {t("twoFactorEnableButton")}
          </Button>
        )}
      </div>

      {/* Password confirmation before enabling */}
      <Dialog open={step === "password"} onOpenChange={(open) => !open && closeAndReset()}>
        <DialogContent className="max-w-sm">
          <DialogHeader>
            <DialogTitle>{t("twoFactorConfirmPasswordTitle")}</DialogTitle>
            <DialogDescription>{t("twoFactorConfirmPasswordDescription")}</DialogDescription>
          </DialogHeader>
          <div className="space-y-2">
            <Label htmlFor="two-factor-password">{t("currentPassword")}</Label>
            <Input
              id="two-factor-password"
              type="password"
              value={password}
              onChange={(e) => setPassword(e.target.value)}
              autoComplete="current-password"
              autoFocus
            />
            {error && <p className="text-sm text-destructive">{error}</p>}
          </div>
          <DialogFooter>
            <Button variant="ghost" onClick={closeAndReset} disabled={busy}>{t("twoFactorCancel")}</Button>
            <Button onClick={() => void startEnable()} disabled={busy || !password}>
              {busy ? t("saving") : t("twoFactorContinue")}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* QR + backup codes + confirmation code */}
      <Dialog open={step === "setup"} onOpenChange={(open) => !open && closeAndReset()}>
        <DialogContent className="max-w-sm">
          <DialogHeader>
            <DialogTitle>{t("twoFactorSetupTitle")}</DialogTitle>
            <DialogDescription>{t("twoFactorSetupDescription")}</DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            {qrDataUrl && (
              <div className="flex justify-center">
                {/* eslint-disable-next-line @next/next/no-img-element -- a data: URL generated client-side, not an optimizable remote image */}
                <img src={qrDataUrl} alt={t("twoFactorQrAlt")} className="h-40 w-40" />
              </div>
            )}

            <div className="space-y-1.5">
              <p className="text-xs font-medium uppercase tracking-wide text-muted-foreground">{t("twoFactorBackupCodesLabel")}</p>
              <div className="rounded-lg border bg-muted/40 p-3 grid grid-cols-2 gap-1 font-mono text-xs">
                {backupCodes.map((c) => <span key={c}>{c}</span>)}
              </div>
              <Button type="button" variant="outline" size="sm" className="w-full" onClick={() => void copyBackupCodes()}>
                {copied ? <Check className="h-3.5 w-3.5" /> : <Copy className="h-3.5 w-3.5" />}
                {copied ? t("twoFactorCodesCopied") : t("twoFactorCopyCodes")}
              </Button>
              <p className="text-xs text-muted-foreground">{t("twoFactorBackupCodesHint")}</p>
            </div>

            <div className="space-y-2">
              <Label htmlFor="two-factor-confirm-code">{t("twoFactorCodeLabel")}</Label>
              <Input
                id="two-factor-confirm-code"
                value={confirmCode}
                onChange={(e) => setConfirmCode(e.target.value)}
                inputMode="numeric"
                placeholder="000000"
                autoComplete="one-time-code"
              />
              {error && <p className="text-sm text-destructive">{error}</p>}
            </div>
          </div>
          <DialogFooter>
            <Button variant="ghost" onClick={closeAndReset} disabled={busy}>{t("twoFactorCancel")}</Button>
            <Button onClick={() => void confirmEnable()} disabled={busy || !confirmCode.trim()}>
              {busy ? t("saving") : t("twoFactorVerifyAndEnable")}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Password confirmation before disabling */}
      <Dialog open={step === "disable-password"} onOpenChange={(open) => !open && closeAndReset()}>
        <DialogContent className="max-w-sm">
          <DialogHeader>
            <DialogTitle>{t("twoFactorDisableTitle")}</DialogTitle>
            <DialogDescription>{t("twoFactorDisableDescription")}</DialogDescription>
          </DialogHeader>
          {hasPassword && (
            <div className="space-y-2">
              <Label htmlFor="two-factor-disable-password">{t("currentPassword")}</Label>
              <Input
                id="two-factor-disable-password"
                type="password"
                value={password}
                onChange={(e) => setPassword(e.target.value)}
                autoComplete="current-password"
                autoFocus
              />
            </div>
          )}
          {error && <p className="text-sm text-destructive">{error}</p>}
          <DialogFooter>
            <Button variant="ghost" onClick={closeAndReset} disabled={busy}>{t("twoFactorCancel")}</Button>
            <Button
              variant="destructive"
              onClick={() => void handleDisable()}
              disabled={busy || (hasPassword && !password)}
            >
              {busy ? t("saving") : t("twoFactorDisableButton")}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </section>
  );
}
