"use client"

import type React from "react"
import { useEffect, useRef, useState } from "react"
import { useRouter } from "next/navigation"
import { Mail, ArrowLeft, CheckCircle2, KeyRound, Lock } from "lucide-react"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { TwoFactorSetupForm, TwoFactorVerifyForm } from "@/components/two-factor-flow"

const RESEND_COOLDOWN = 30 // seconds

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"
}

function isValidEmail(value: string) {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value.trim())
}

// ADR-021 Beslutning E: primær-autentisering (magic-link ELLER passord) kan
// returnere tre ulike utfall -- delt mellom denne komponenten og
// verify-form.tsx sin håndtering av magic-link-svaret.
type PostAuthMode = "2fa-verify" | "2fa-setup" | null

export function LoginForm() {
  const router = useRouter()
  const [mode, setMode] = useState<"email" | "code" | "password">("email")
  const [postAuth, setPostAuth] = useState<PostAuthMode>(null)
  const [twoFactorMethod, setTwoFactorMethod] = useState<"totp" | "email" | null>(null)
  const [email, setEmail] = useState("")
  const [touched, setTouched] = useState(false)
  const [sent, setSent] = useState(false)
  const [sending, setSending] = useState(false)
  const [cooldown, setCooldown] = useState(0)
  const [error, setError] = useState<string | null>(null)

  function handleLoginResult(result: LoginResult) {
    if (result.status === "success") {
      router.replace("/dashboard")
    } else if (result.status === "2fa_required") {
      setTwoFactorMethod(result.two_factor_method ?? "totp")
      setPostAuth("2fa-verify")
    } else {
      setPostAuth("2fa-setup")
    }
  }

  function handleTwoFactorSuccess() {
    router.replace("/dashboard")
  }

  const emailValid = isValidEmail(email)
  const showError = touched && email.length > 0 && !emailValid

  // Countdown timer for the resend cooldown.
  useEffect(() => {
    if (cooldown <= 0) return
    const id = setInterval(() => {
      setCooldown((c) => (c <= 1 ? 0 : c - 1))
    }, 1000)
    return () => clearInterval(id)
  }, [cooldown])

  async function sendLink() {
    setSending(true)
    setError(null)
    try {
      // Alltid samme suksess-respons uansett om e-posten finnes (anti-
      // enumerering, se ADR-009) -- kun nettverks-/serverfeil havner i catch.
      const res = await fetch("/auth/request-link", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        credentials: "include",
        body: JSON.stringify({ email: email.trim(), locale: "nb" }),
      })
      if (!res.ok) throw new Error(`request-link: ${res.status}`)
      setSent(true)
      setCooldown(RESEND_COOLDOWN)
    } catch {
      setError("Klarte ikke å sende lenken. Sjekk tilkoblingen og prøv igjen.")
    } finally {
      setSending(false)
    }
  }

  function handleSubmit(e: React.FormEvent) {
    e.preventDefault()
    setTouched(true)
    if (!emailValid || sending) return
    void sendLink()
  }

  function handleResend() {
    if (cooldown > 0 || sending) return
    void sendLink()
  }

  function handleReset() {
    setSent(false)
    setTouched(false)
  }

  return (
    <div className="w-full rounded-3xl border border-border bg-card p-6 shadow-lg shadow-black/5 sm:p-8">
      {postAuth === "2fa-verify" ? (
        <TwoFactorVerifyForm
          method={twoFactorMethod ?? "totp"}
          onSuccess={handleTwoFactorSuccess}
          onBack={() => setPostAuth(null)}
        />
      ) : postAuth === "2fa-setup" ? (
        <TwoFactorSetupForm forced onSuccess={handleTwoFactorSuccess} />
      ) : sent ? (
        <ConfirmationState
          email={email}
          cooldown={cooldown}
          sending={sending}
          error={error}
          onResend={handleResend}
          onReset={handleReset}
        />
      ) : mode === "code" ? (
        <JoinByCode onBack={() => setMode("email")} />
      ) : mode === "password" ? (
        <PasswordLoginForm onResult={handleLoginResult} onBack={() => setMode("email")} />
      ) : (
        <form onSubmit={handleSubmit} className="flex flex-col gap-6" noValidate>
          <div className="flex flex-col gap-2">
            <Label htmlFor="email" className="text-sm font-semibold">
              E-post
            </Label>
            <div className="relative">
              <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="email"
                type="email"
                inputMode="email"
                autoComplete="email"
                autoFocus
                placeholder="deg@epost.no"
                value={email}
                onChange={(e) => setEmail(e.target.value)}
                onBlur={() => setTouched(true)}
                aria-invalid={showError}
                aria-describedby={showError ? "email-error" : undefined}
                className="h-14 rounded-2xl pl-11 text-base"
              />
            </div>
            {showError && (
              <p id="email-error" className="text-sm font-medium text-destructive">
                Skriv inn en gyldig e-postadresse.
              </p>
            )}
          </div>

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

          <Button
            type="submit"
            disabled={sending}
            className="h-14 rounded-2xl text-base font-bold shadow-sm"
          >
            {sending ? "Sender …" : "Send innloggingslenke"}
          </Button>

          <p className="text-center text-sm leading-relaxed text-muted-foreground text-pretty">
            Ingen passord nødvendig. Vi sender deg en sikker lenke på e-post.
          </p>

          <div className="flex flex-col gap-2">
            <button
              type="button"
              onClick={() => setMode("password")}
              className="inline-flex items-center justify-center gap-1.5 text-sm font-semibold text-muted-foreground transition-colors hover:text-foreground"
            >
              <Lock aria-hidden="true" className="size-4" />
              Logg inn med e-post og passord i stedet
            </button>
            <button
              type="button"
              onClick={() => setMode("code")}
              className="inline-flex items-center justify-center gap-1.5 text-sm font-semibold text-muted-foreground transition-colors hover:text-foreground"
            >
              <KeyRound aria-hidden="true" className="size-4" />
              Har du en invitasjonskode? Gå rett til turneringen
            </button>
          </div>
        </form>
      )}
    </div>
  )
}

// --- Passord-innlogging (ADR-021 Beslutning A) -- et sidestilt, valgfritt
// alternativ til magic-link, ALDRI en erstatning. -----------------------

function PasswordLoginForm({
  onResult,
  onBack,
}: {
  onResult: (result: LoginResult) => void
  onBack: () => void
}) {
  const [email, setEmail] = useState("")
  const [password, setPassword] = useState("")
  const [submitting, setSubmitting] = useState(false)
  const [error, setError] = useState<string | null>(null)

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault()
    if (!email.trim() || !password || submitting) return
    setSubmitting(true)
    setError(null)
    try {
      const res = await fetch("/auth/login-password", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        credentials: "include",
        body: JSON.stringify({ email: email.trim(), password }),
      })
      if (!res.ok) {
        const body = await res.json().catch(() => null)
        throw new Error(body?.detail?.message ?? "E-post eller passord er feil.")
      }
      onResult(await res.json())
    } 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 gap-2">
        <Label htmlFor="pw-email" className="text-sm font-semibold">
          E-post
        </Label>
        <div className="relative">
          <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="pw-email"
            type="email"
            inputMode="email"
            autoComplete="email"
            autoFocus
            placeholder="deg@epost.no"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            className="h-14 rounded-2xl pl-11 text-base"
          />
        </div>
      </div>

      <div className="flex flex-col gap-2">
        <Label htmlFor="pw-password" className="text-sm font-semibold">
          Passord
        </Label>
        <div className="relative">
          <Lock
            aria-hidden="true"
            className="pointer-events-none absolute left-3.5 top-1/2 size-5 -translate-y-1/2 text-muted-foreground"
          />
          {/* Bevisst ingen begrensning på tegn -- spesialtegn/mellomrom skal fungere. */}
          <Input
            id="pw-password"
            type="password"
            autoComplete="current-password"
            placeholder="Passordet ditt"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            className="h-14 rounded-2xl pl-11 text-base"
          />
        </div>
      </div>

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

      <Button
        type="submit"
        disabled={submitting || !email.trim() || !password}
        className="h-14 rounded-2xl text-base font-bold shadow-sm"
      >
        {submitting ? "Logger inn …" : "Logg inn"}
      </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" />
        Bruk innloggingslenke på e-post i stedet
      </button>
    </form>
  )
}

// --- Kode-innlogging (ADR-020): tar deg rett til en turnering via en kort,
// menneske-skrivbar kode -- FØR innlogging, og uansett turneringens
// synlighet (koden ER selve invitasjonen, se ADR-020 Beslutning A). ---------

function JoinByCode({ onBack }: { onBack: () => void }) {
  const router = useRouter()
  const [code, setCode] = useState("")
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault()
    const trimmed = code.trim()
    if (!trimmed || loading) return
    setLoading(true)
    setError(null)
    try {
      const res = await fetch(`/public/tournaments/by-code/${encodeURIComponent(trimmed)}`)
      if (!res.ok) {
        const body = await res.json().catch(() => null)
        setError(body?.detail?.message ?? "Fant ingen turnering med denne koden.")
        return
      }
      const data: { tournament_id: string } = await res.json()
      router.push(`/t/${data.tournament_id}?code=${encodeURIComponent(trimmed)}`)
    } catch {
      setError("Klarte ikke å slå opp koden. Sjekk tilkoblingen og prøv igjen.")
    } finally {
      setLoading(false)
    }
  }

  return (
    <form onSubmit={handleSubmit} className="flex flex-col gap-6" noValidate>
      <div className="flex flex-col gap-2">
        <Label htmlFor="join-code" className="text-sm font-semibold">
          Invitasjonskode
        </Label>
        <div className="relative">
          <KeyRound
            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="join-code"
            type="text"
            autoCapitalize="characters"
            autoComplete="off"
            autoFocus
            placeholder="F.eks. RAPWAR"
            value={code}
            onChange={(e) => setCode(e.target.value.toUpperCase())}
            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={loading || !code.trim()}
        className="h-14 rounded-2xl text-base font-bold shadow-sm"
      >
        {loading ? "Sjekker …" : "Gå til turnering"}
      </Button>

      <p className="text-center text-sm leading-relaxed text-muted-foreground text-pretty">
        Fått en kode muntlig eller på en lapp? Skriv den inn her — du trenger ikke logge inn for
        å se turneringen eller melde deg på.
      </p>

      <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>
  )
}

function ConfirmationState({
  email,
  cooldown,
  sending,
  error,
  onResend,
  onReset,
}: {
  email: string
  cooldown: number
  sending: boolean
  error: string | null
  onResend: () => void
  onReset: () => void
}) {
  const liveRef = useRef<HTMLHeadingElement>(null)

  useEffect(() => {
    liveRef.current?.focus()
  }, [])

  return (
    <div className="flex flex-col items-center gap-5 text-center">
      <div className="flex size-16 items-center justify-center rounded-2xl bg-primary/15">
        <CheckCircle2 aria-hidden="true" className="size-8 text-primary" />
      </div>

      <div className="flex flex-col gap-2">
        <h2
          ref={liveRef}
          tabIndex={-1}
          className="text-2xl font-extrabold tracking-tight outline-none text-balance"
        >
          Sjekk innboksen din
        </h2>
        <p className="text-sm leading-relaxed text-muted-foreground text-pretty">
          Vi har sendt en innloggingslenke til{" "}
          <span className="font-semibold text-foreground">{email}</span>. Åpne den på denne enheten for å logge inn.
        </p>
      </div>

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

      <div className="mt-1 w-full">
        {cooldown > 0 ? (
          <p className="text-sm text-muted-foreground" aria-live="polite">
            Fikk du ingen e-post? Send på nytt om{" "}
            <span className="font-semibold text-foreground tabular-nums">{cooldown}s</span>
          </p>
        ) : (
          <Button
            type="button"
            variant="ghost"
            onClick={onResend}
            disabled={sending}
            className="h-11 rounded-xl font-semibold text-primary hover:bg-primary/10 hover:text-primary"
          >
            {sending ? "Sender …" : "Send lenken på nytt"}
          </Button>
        )}
      </div>

      <button
        type="button"
        onClick={onReset}
        className="mt-1 inline-flex items-center gap-1.5 text-sm font-semibold text-muted-foreground transition-colors hover:text-foreground"
      >
        <ArrowLeft aria-hidden="true" className="size-4" />
        Bruk en annen e-post
      </button>
    </div>
  )
}

