"use client"

// Delt mellom login-form.tsx (passord-modus) og verify-form.tsx (magic-link)
// -- begge kan returnere status "2fa_required"/"2fa_setup_required" fra
// backend (ADR-021 Beslutning E), og trenger identisk oppfølging.

import type React from "react"
import { useEffect, useState } from "react"
import { ArrowLeft, KeyRound, Mail, ShieldCheck } from "lucide-react"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

type SessionUser = {
  id: string
  email: string
  display_name: string
  preferred_locale: string
}

type LoginResult = {
  status: "success" | "2fa_required" | "2fa_setup_required"
  user?: SessionUser
  two_factor_method?: "totp" | "email"
}

// --- Verifisering av en PÅGÅENDE innlogging (status "2fa_required") --------

export function TwoFactorVerifyForm({
  method,
  onSuccess,
  onBack,
}: {
  method: "totp" | "email"
  onSuccess: (user: SessionUser) => void
  onBack: () => void
}) {
  const [code, setCode] = useState("")
  const [submitting, setSubmitting] = useState(false)
  const [sendingEmail, setSendingEmail] = useState(false)
  const [emailSent, setEmailSent] = useState(false)
  const [error, setError] = useState<string | null>(null)

  async function requestEmailCode() {
    setSendingEmail(true)
    setError(null)
    try {
      const res = await fetch("/auth/2fa/email/request", { method: "POST", credentials: "include" })
      if (!res.ok) throw new Error("request failed")
      setEmailSent(true)
    } catch {
      setError("Klarte ikke å sende koden. Prøv igjen.")
    } finally {
      setSendingEmail(false)
    }
  }

  useEffect(() => {
    if (method === "email") void requestEmailCode()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [method])

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault()
    if (!code.trim() || submitting) return
    setSubmitting(true)
    setError(null)
    try {
      const res = await fetch("/auth/2fa/verify", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        credentials: "include",
        body: JSON.stringify({ code: code.trim() }),
      })
      if (!res.ok) {
        const body = await res.json().catch(() => null)
        throw new Error(body?.detail?.message ?? "Feil eller utløpt kode.")
      }
      const result: LoginResult = await res.json()
      if (result.status === "success" && result.user) {
        onSuccess(result.user)
      } else {
        throw new Error("Uventet svar fra serveren.")
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : "Noe gikk galt. Prøv igjen.")
    } finally {
      setSubmitting(false)
    }
  }

  return (
    <form onSubmit={handleSubmit} className="flex flex-col gap-6" noValidate>
      <div className="flex flex-col items-center gap-3 text-center">
        <div className="flex size-14 items-center justify-center rounded-2xl bg-muted">
          <ShieldCheck aria-hidden="true" className="size-7 text-muted-foreground" />
        </div>
        <div className="flex flex-col gap-1">
          <h2 className="text-xl font-extrabold tracking-tight">Topartsautentisering</h2>
          <p className="text-sm leading-relaxed text-muted-foreground text-pretty">
            {method === "totp"
              ? "Skriv inn koden fra autentisator-appen din."
              : emailSent
                ? "Vi har sendt en engangskode til e-posten din."
                : "Sender en engangskode til e-posten din …"}
          </p>
        </div>
      </div>

      <div className="flex flex-col gap-2">
        <Label htmlFor="tfa-code" className="text-sm font-semibold">
          Kode
        </Label>
        <div className="relative">
          {method === "totp" ? (
            <KeyRound
              aria-hidden="true"
              className="pointer-events-none absolute left-3.5 top-1/2 size-5 -translate-y-1/2 text-muted-foreground"
            />
          ) : (
            <Mail
              aria-hidden="true"
              className="pointer-events-none absolute left-3.5 top-1/2 size-5 -translate-y-1/2 text-muted-foreground"
            />
          )}
          <Input
            id="tfa-code"
            type="text"
            inputMode="numeric"
            autoComplete="one-time-code"
            autoFocus
            placeholder="123456"
            value={code}
            onChange={(e) => setCode(e.target.value)}
            className="h-14 rounded-2xl pl-11 text-base tracking-widest"
          />
        </div>
      </div>

      {error && (
        <p role="alert" className="text-center text-sm font-medium text-destructive">
          {error}
        </p>
      )}

      <Button
        type="submit"
        disabled={submitting || !code.trim()}
        className="h-14 rounded-2xl text-base font-bold shadow-sm"
      >
        {submitting ? "Bekrefter …" : "Bekreft"}
      </Button>

      {method === "email" && (
        <button
          type="button"
          onClick={requestEmailCode}
          disabled={sendingEmail}
          className="text-center text-sm font-semibold text-muted-foreground transition-colors hover:text-foreground"
        >
          {sendingEmail ? "Sender …" : "Send koden på nytt"}
        </button>
      )}

      <button
        type="button"
        onClick={onBack}
        className="inline-flex items-center justify-center gap-1.5 text-sm font-semibold text-muted-foreground transition-colors hover:text-foreground"
      >
        <ArrowLeft aria-hidden="true" className="size-4" />
        Tilbake til innlogging
      </button>
    </form>
  )
}

// --- Oppsett av 2FA (status "2fa_setup_required" ELLER frivillig fra
// kontoinnstillinger) -------------------------------------------------

type SetupStartResult = {
  status: "totp_ready" | "email_sent"
  secret?: string
  otpauth_uri?: string
  qr_code_data_uri?: string
}

export function TwoFactorSetupForm({
  forced,
  onSuccess,
}: {
  forced: boolean
  onSuccess: (user: SessionUser) => void
}) {
  const [method, setMethod] = useState<"totp" | "email" | null>(null)
  const [starting, setStarting] = useState(false)
  const [setupInfo, setSetupInfo] = useState<SetupStartResult | null>(null)
  const [code, setCode] = useState("")
  const [confirming, setConfirming] = useState(false)
  const [error, setError] = useState<string | null>(null)

  async function chooseMethod(chosen: "totp" | "email") {
    setMethod(chosen)
    setStarting(true)
    setError(null)
    try {
      const res = await fetch("/auth/2fa/setup/start", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        credentials: "include",
        body: JSON.stringify({ method: chosen }),
      })
      if (!res.ok) throw new Error("start failed")
      setSetupInfo(await res.json())
    } catch {
      setError("Klarte ikke å starte oppsettet. Prøv igjen.")
      setMethod(null)
    } finally {
      setStarting(false)
    }
  }

  async function handleConfirm(e: React.FormEvent) {
    e.preventDefault()
    if (!method || !code.trim() || confirming) return
    setConfirming(true)
    setError(null)
    try {
      const res = await fetch("/auth/2fa/setup/confirm", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        credentials: "include",
        body: JSON.stringify({ method, code: code.trim(), secret: setupInfo?.secret }),
      })
      if (!res.ok) {
        const body = await res.json().catch(() => null)
        throw new Error(body?.detail?.message ?? "Feil kode.")
      }
      const user: SessionUser = await res.json()
      onSuccess(user)
    } catch (err) {
      setError(err instanceof Error ? err.message : "Noe gikk galt. Prøv igjen.")
    } finally {
      setConfirming(false)
    }
  }

  if (!method) {
    return (
      <div className="flex flex-col gap-6">
        <div className="flex flex-col items-center gap-3 text-center">
          <div className="flex size-14 items-center justify-center rounded-2xl bg-muted">
            <ShieldCheck aria-hidden="true" className="size-7 text-muted-foreground" />
          </div>
          <div className="flex flex-col gap-1">
            <h2 className="text-xl font-extrabold tracking-tight">Sett opp topartsautentisering</h2>
            <p className="text-sm leading-relaxed text-muted-foreground text-pretty">
              {forced
                ? "Som organisasjonseier/administrator må du sette opp 2FA før du kan fortsette."
                : "Velg hvilken metode du ønsker."}
            </p>
          </div>
        </div>

        {error && (
          <p role="alert" className="text-center text-sm font-medium text-destructive">
            {error}
          </p>
        )}

        <div className="flex flex-col gap-3">
          <Button
            type="button"
            disabled={starting}
            onClick={() => void chooseMethod("totp")}
            className="h-14 rounded-2xl text-base font-bold shadow-sm"
          >
            <KeyRound aria-hidden="true" className="size-5" />
            Autentisator-app (TOTP)
          </Button>
          <Button
            type="button"
            variant="outline"
            disabled={starting}
            onClick={() => void chooseMethod("email")}
            className="h-14 rounded-2xl text-base font-bold"
          >
            <Mail aria-hidden="true" className="size-5" />
            Engangskode på e-post
          </Button>
        </div>
      </div>
    )
  }

  return (
    <form onSubmit={handleConfirm} className="flex flex-col gap-6" noValidate>
      <div className="flex flex-col items-center gap-3 text-center">
        <div className="flex size-14 items-center justify-center rounded-2xl bg-muted">
          <ShieldCheck aria-hidden="true" className="size-7 text-muted-foreground" />
        </div>
        <h2 className="text-xl font-extrabold tracking-tight">Bekreft oppsettet</h2>
      </div>

      {method === "totp" && setupInfo?.qr_code_data_uri && (
        <div className="flex flex-col items-center gap-3">
          {/* eslint-disable-next-line @next/next/no-img-element -- data-URI, ingen next/image-fordel */}
          <img
            src={setupInfo.qr_code_data_uri || "/placeholder.svg"}
            alt="QR-kode for autentisator-app"
            className="size-48 rounded-2xl border border-border"
          />
          <p className="text-center text-xs leading-relaxed text-muted-foreground text-pretty">
            Skann QR-koden med autentisator-appen din, eller skriv inn denne koden manuelt:{" "}
            <span className="font-mono font-semibold text-foreground">{setupInfo.secret}</span>
          </p>
        </div>
      )}

      {method === "email" && (
        <p className="text-center text-sm text-muted-foreground text-pretty">
          Vi har sendt en engangskode til e-posten din.
        </p>
      )}

      <div className="flex flex-col gap-2">
        <Label htmlFor="setup-code" className="text-sm font-semibold">
          Bekreftelseskode
        </Label>
        <Input
          id="setup-code"
          type="text"
          inputMode="numeric"
          autoComplete="one-time-code"
          autoFocus
          placeholder="123456"
          value={code}
          onChange={(e) => setCode(e.target.value)}
          className="h-14 rounded-2xl text-base tracking-widest"
        />
      </div>

      {error && (
        <p role="alert" className="text-center text-sm font-medium text-destructive">
          {error}
        </p>
      )}

      <Button
        type="submit"
        disabled={confirming || !code.trim()}
        className="h-14 rounded-2xl text-base font-bold shadow-sm"
      >
        {confirming ? "Bekrefter …" : "Aktiver 2FA"}
      </Button>

      <button
        type="button"
        onClick={() => {
          setMethod(null)
          setSetupInfo(null)
          setCode("")
        }}
        className="inline-flex items-center justify-center gap-1.5 text-sm font-semibold text-muted-foreground transition-colors hover:text-foreground"
      >
        <ArrowLeft aria-hidden="true" className="size-4" />
        Velg en annen metode
      </button>
    </form>
  )
}
