"use client"

import type React from "react"
import { useEffect, useId, useState } from "react"
import { useRouter } from "next/navigation"
import { cn } from "@/lib/utils"
import { TwoFactorSetupForm, TwoFactorVerifyForm } from "@/components/two-factor-flow"

/* ------------------------------------------------------------------ */
/* Icons — inline SVG (currentColor), so every action can pair an      */
/* icon with a real text label and we control size/stroke precisely.   */
/* ------------------------------------------------------------------ */
type IconProps = { className?: string }
const stroke = {
  fill: "none",
  stroke: "currentColor",
  strokeWidth: 1.75,
  strokeLinecap: "round" as const,
  strokeLinejoin: "round" as const,
}
function MailIcon({ className }: IconProps) {
  return (
    <svg viewBox="0 0 24 24" className={className} aria-hidden="true" {...stroke}>
      <rect x="3" y="5" width="18" height="14" rx="2.5" />
      <path d="m4 7 8 6 8-6" />
    </svg>
  )
}
function KeyIcon({ className }: IconProps) {
  return (
    <svg viewBox="0 0 24 24" className={className} aria-hidden="true" {...stroke}>
      <circle cx="8" cy="15" r="4.5" />
      <path d="M11 12 21 2m-4 1 3 3m-6 0 3 3" />
    </svg>
  )
}
function TicketIcon({ className }: IconProps) {
  return (
    <svg viewBox="0 0 24 24" className={className} aria-hidden="true" {...stroke}>
      <path d="M3 8.5A1.5 1.5 0 0 1 4.5 7h15A1.5 1.5 0 0 1 21 8.5V10a2 2 0 0 0 0 4v1.5a1.5 1.5 0 0 1-1.5 1.5h-15A1.5 1.5 0 0 1 3 15.5V14a2 2 0 0 0 0-4Z" />
      <path d="M14 7v10" strokeDasharray="1.5 2.5" />
    </svg>
  )
}
function EyeIcon({ className }: IconProps) {
  return (
    <svg viewBox="0 0 24 24" className={className} aria-hidden="true" {...stroke}>
      <path d="M2.5 12S6 5.5 12 5.5 21.5 12 21.5 12 18 18.5 12 18.5 2.5 12 2.5 12Z" />
      <circle cx="12" cy="12" r="3" />
    </svg>
  )
}
function EyeOffIcon({ className }: IconProps) {
  return (
    <svg viewBox="0 0 24 24" className={className} aria-hidden="true" {...stroke}>
      <path d="M3 3l18 18" />
      <path d="M10.6 6.1A9.7 9.7 0 0 1 12 6c6 0 9.5 6 9.5 6a16 16 0 0 1-3.3 3.9M6.3 7.9A16 16 0 0 0 2.5 12S6 18 12 18a9.5 9.5 0 0 0 3.4-.6" />
      <path d="M9.9 9.9a3 3 0 0 0 4.2 4.2" />
    </svg>
  )
}
function ArrowLeftIcon({ className }: IconProps) {
  return (
    <svg viewBox="0 0 24 24" className={className} aria-hidden="true" {...stroke}>
      <path d="M11 5 4 12l7 7M4 12h16" />
    </svg>
  )
}
function AlertIcon({ className }: IconProps) {
  return (
    <svg viewBox="0 0 24 24" className={className} aria-hidden="true" {...stroke}>
      <path d="M12 3.5 1.8 20.5h20.4L12 3.5Z" />
      <path d="M12 10v4.5" />
      <circle cx="12" cy="17.6" r="0.4" fill="currentColor" stroke="none" />
    </svg>
  )
}
function CheckIcon({ className }: IconProps) {
  return (
    <svg viewBox="0 0 24 24" className={className} aria-hidden="true" {...stroke}>
      <path d="m4 12.5 5 5 11-11" />
    </svg>
  )
}
function FlagIcon({ className }: IconProps) {
  return (
    <svg viewBox="0 0 24 24" className={className} aria-hidden="true" {...stroke}>
      <path d="M6 21V4" />
      <path d="M6 4.5c3-2 6 1.5 9 0V13c-3 1.5-6-2-9 0" fill="var(--cup)" stroke="none" />
      <path d="M6 4.5c3-2 6 1.5 9 0V13c-3 1.5-6-2-9 0" />
      <circle cx="6" cy="21" r="1.6" fill="currentColor" stroke="none" />
    </svg>
  )
}
function Spinner({ className }: IconProps) {
  return (
    <svg viewBox="0 0 24 24" className={cn("animate-spin", className)} aria-hidden="true" fill="none">
      <circle cx="12" cy="12" r="9" stroke="currentColor" strokeOpacity="0.25" strokeWidth="2.5" />
      <path d="M21 12a9 9 0 0 0-9-9" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" />
    </svg>
  )
}

/* ------------------------------------------------------------------ */
/* Shared styles                                                       */
/* ------------------------------------------------------------------ */
const focusRing =
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-tee-strong focus-visible:ring-offset-2 focus-visible:ring-offset-clubhouse-card"

const inputBase =
  "w-full h-12 rounded-xl border bg-clubhouse-field px-4 text-base text-clubhouse-ink placeholder:text-clubhouse-muted/70 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-tee-strong/70"

const primaryBtn = cn(
  "inline-flex w-full min-h-[3.25rem] items-center justify-center gap-2 rounded-xl bg-tee-strong px-5 text-base font-semibold text-white shadow-sm transition-colors hover:bg-[#265a18] active:translate-y-px disabled:cursor-not-allowed disabled:opacity-55",
  focusRing,
)

const secondaryBtn = cn(
  "inline-flex w-full min-h-[2.75rem] items-center justify-center gap-2 rounded-xl border border-clubhouse-border bg-clubhouse-card px-4 py-2.5 text-base font-medium text-clubhouse-ink transition-colors hover:border-tee-strong/40 hover:bg-clubhouse-field",
  focusRing,
)

const backBtn = cn(
  "-mx-2 inline-flex min-h-[2.75rem] items-center gap-1.5 rounded-lg px-2 text-base font-medium text-tee-strong transition-colors hover:underline",
  focusRing,
)

const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
const RESEND_SECONDS = 30

type Mode = "email" | "sent" | "password" | "code"
type PostAuthMode = "2fa-verify" | "2fa-setup" | null

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

/* ------------------------------------------------------------------ */
/* Small building blocks                                               */
/* ------------------------------------------------------------------ */
function FieldError({ id, children }: { id: string; children: React.ReactNode }) {
  return (
    <p id={id} role="alert" className="mt-1.5 flex items-start gap-1.5 text-[0.9375rem] font-medium text-cup-strong">
      <AlertIcon className="mt-0.5 size-4 shrink-0" />
      <span>{children}</span>
    </p>
  )
}

function FormAlert({ children }: { children: React.ReactNode }) {
  return (
    <div
      role="alert"
      className="flex items-start gap-2.5 rounded-xl border border-cup-strong/45 bg-cup/10 px-4 py-3 text-[0.9375rem] leading-snug text-clubhouse-ink"
    >
      <AlertIcon className="mt-0.5 size-5 shrink-0 text-cup-strong" />
      <span>{children}</span>
    </div>
  )
}

/* ------------------------------------------------------------------ */
/* Main component                                                      */
/* ------------------------------------------------------------------ */
export function TeeCupAuth() {
  const router = useRouter()
  const [mode, setMode] = useState<Mode>("email")
  const [postAuth, setPostAuth] = useState<PostAuthMode>(null)
  const [twoFactorMethod, setTwoFactorMethod] = useState<"totp" | "email">("totp")

  // shared field state (email persists across email <-> password)
  const [email, setEmail] = useState("")
  const [emailTouched, setEmailTouched] = useState(false)

  const emailInvalid = emailTouched && email.length > 0 && !EMAIL_RE.test(email)
  const emailIds = useId()
  const emailErrId = `${emailIds}-email-err`

  /* form-level (server) error, shared across states */
  const [formError, setFormError] = useState<string | null>(null)
  const [loading, setLoading] = useState(false)

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

  /* ---- State 1: magic link, ekte /auth/request-link ---- */
  async function handleSendLink(e: React.FormEvent) {
    e.preventDefault()
    setEmailTouched(true)
    if (!EMAIL_RE.test(email) || loading) return
    setFormError(null)
    setLoading(true)
    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}`)
      setMode("sent")
      setCooldown(RESEND_SECONDS)
    } catch {
      setFormError("Klarte ikke å sende lenken. Sjekk tilkoblingen og prøv igjen.")
    } finally {
      setLoading(false)
    }
  }

  /* ---- State 2: cooldown ---- */
  const [cooldown, setCooldown] = useState(0)
  const [resentNote, setResentNote] = useState(false)
  useEffect(() => {
    if (cooldown <= 0) return
    const t = setInterval(() => setCooldown((c) => (c <= 1 ? 0 : c - 1)), 1000)
    return () => clearInterval(t)
  }, [cooldown])

  async function handleResend() {
    if (cooldown > 0 || loading) return
    setResentNote(false)
    setFormError(null)
    setLoading(true)
    try {
      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}`)
      setCooldown(RESEND_SECONDS)
      setResentNote(true)
    } catch {
      setFormError("Klarte ikke å sende lenken. Sjekk tilkoblingen og prøv igjen.")
    } finally {
      setLoading(false)
    }
  }

  /* ---- State 3: password, ekte /auth/login-password ---- */
  const [password, setPassword] = useState("")
  const [showPassword, setShowPassword] = useState(false)
  const pwIds = useId()

  async function handlePasswordLogin(e: React.FormEvent) {
    e.preventDefault()
    if (!email.trim() || !password || loading) return
    setFormError(null)
    setLoading(true)
    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.")
      }
      handleLoginResult(await res.json())
    } catch (err) {
      setFormError(err instanceof Error ? err.message : "Noe gikk galt. Prøv igjen.")
    } finally {
      setLoading(false)
    }
  }

  /* ---- State 4: join by code, ekte /public/tournaments/by-code ---- */
  const [code, setCode] = useState("")
  async function handleJoin(e: React.FormEvent) {
    e.preventDefault()
    const trimmed = code.trim()
    if (!trimmed || loading) return
    setFormError(null)
    setLoading(true)
    try {
      const res = await fetch(`/public/tournaments/by-code/${encodeURIComponent(trimmed)}`)
      if (!res.ok) {
        const body = await res.json().catch(() => null)
        throw new Error(body?.detail?.message ?? "Fant ingen turnering med denne koden.")
      }
      const data: { tournament_id: string } = await res.json()
      router.push(`/t/${data.tournament_id}?code=${encodeURIComponent(trimmed)}`)
    } catch (err) {
      setFormError(err instanceof Error ? err.message : "Klarte ikke å slå opp koden. Sjekk tilkoblingen og prøv igjen.")
    } finally {
      setLoading(false)
    }
  }

  // Reset transient per-mode state when switching modes.
  function switchMode(next: Mode, opts?: { clearEmail?: boolean }) {
    setFormError(null)
    setPassword("")
    setShowPassword(false)
    setResentNote(false)
    if (opts?.clearEmail) {
      setEmail("")
      setEmailTouched(false)
    }
    if (next === "code") setCode("")
    setMode(next)
  }

  /* ---------------- 2FA continuation (shared with password login) --- */
  if (postAuth === "2fa-verify") {
    return (
      <TwoFactorVerifyForm
        method={twoFactorMethod}
        onSuccess={handleTwoFactorSuccess}
        onBack={() => setPostAuth(null)}
      />
    )
  }
  if (postAuth === "2fa-setup") {
    return <TwoFactorSetupForm forced onSuccess={handleTwoFactorSuccess} />
  }

  return (
    <div>
      {/* ---------- State 1: Magic link (primary path) ---------- */}
      {mode === "email" && (
        <form onSubmit={handleSendLink} noValidate>
          <h2 className="text-balance text-xl font-bold text-clubhouse-ink">Logg inn</h2>
          <p className="mt-1.5 text-pretty text-base leading-relaxed text-clubhouse-muted">
            Klart for en runde? Skriv inn e-posten din, så sender vi deg en lenke.
          </p>

          <div className="mt-6">
            <label htmlFor="email" className="mb-1.5 block text-[0.9375rem] font-semibold text-clubhouse-ink">
              E-post
            </label>
            <input
              id="email"
              name="email"
              type="email"
              inputMode="email"
              autoComplete="email"
              autoFocus
              enterKeyHint="go"
              placeholder="deg@eksempel.no"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              onBlur={() => setEmailTouched(true)}
              aria-invalid={emailInvalid || undefined}
              aria-describedby={emailInvalid ? emailErrId : undefined}
              className={cn(inputBase, emailInvalid ? "border-cup-strong ring-2 ring-cup-strong/30" : "border-clubhouse-border")}
            />
            {emailInvalid && <FieldError id={emailErrId}>Skriv inn en gyldig e-postadresse, f.eks. navn@klubb.no.</FieldError>}
          </div>

          {formError && <div className="mt-4">{<FormAlert>{formError}</FormAlert>}</div>}

          <button type="submit" disabled={loading} className={cn(primaryBtn, "mt-5")}>
            {loading ? <Spinner className="size-5" /> : <MailIcon className="size-5" />}
            {loading ? "Sender …" : "Send innloggingslenke"}
          </button>
          <p className="mt-3 text-pretty text-[0.9375rem] leading-relaxed text-clubhouse-muted">
            Ingen passord nødvendig. Vi sender deg en sikker lenke på e-post.
          </p>

          <div className="mt-7 border-t border-clubhouse-border pt-5">
            <div className="grid gap-2.5">
              <button type="button" className={secondaryBtn} onClick={() => switchMode("password")}>
                <KeyIcon className="size-5 text-tee-strong" />
                Logg inn med e-post og passord i stedet
              </button>
              <button type="button" className={secondaryBtn} onClick={() => switchMode("code")}>
                <TicketIcon className="size-5 text-cup-strong" />
                Har du en invitasjonskode? Gå rett til turneringen
              </button>
            </div>
          </div>
        </form>
      )}

      {/* ---------- State 2: Link sent ---------- */}
      {mode === "sent" && (
        <div>
          <div className="mb-5 flex size-14 items-center justify-center rounded-2xl bg-tee/20 text-tee-strong">
            <MailIcon className="size-7" />
          </div>
          <h2 className="text-balance text-xl font-bold text-clubhouse-ink">Lenke sendt</h2>
          <p className="mt-2 text-pretty text-base leading-relaxed text-clubhouse-ink">
            Vi sendte en innloggingslenke til <span className="font-semibold break-all">{email}</span>.
          </p>
          <p className="mt-2 text-pretty text-[0.9375rem] leading-relaxed text-clubhouse-muted">
            Åpne lenken på denne enheten for å logge inn. Det kan ta et minutt før den kommer frem.
          </p>

          {formError && <div className="mt-4">{<FormAlert>{formError}</FormAlert>}</div>}

          {resentNote && !formError && (
            <p role="status" className="mt-4 flex items-center gap-2 text-[0.9375rem] font-medium text-tee-strong">
              <CheckIcon className="size-5 shrink-0" />
              Lenken er sendt på nytt.
            </p>
          )}

          <button type="button" onClick={handleResend} disabled={cooldown > 0 || loading} className={cn(primaryBtn, "mt-6")}>
            {loading ? <Spinner className="size-5" /> : <MailIcon className="size-5" />}
            {loading ? "Sender …" : cooldown > 0 ? `Send igjen om ${cooldown}s` : "Send lenken igjen"}
          </button>

          <div className="mt-6">
            <button type="button" className={backBtn} onClick={() => switchMode("email", { clearEmail: true })}>
              <ArrowLeftIcon className="size-5" />
              Bruk en annen e-postadresse
            </button>
          </div>
        </div>
      )}

      {/* ---------- State 3: Password fallback ---------- */}
      {mode === "password" && (
        <form onSubmit={handlePasswordLogin} noValidate>
          <h2 className="text-balance text-xl font-bold text-clubhouse-ink">Logg inn med passord</h2>
          <p className="mt-1.5 text-pretty text-base leading-relaxed text-clubhouse-muted">
            For deg som har satt et passord på kontoen din.
          </p>

          {formError && <div className="mt-5">{<FormAlert>{formError}</FormAlert>}</div>}

          <div className="mt-5">
            <label htmlFor="email-pw" className="mb-1.5 block text-[0.9375rem] font-semibold text-clubhouse-ink">
              E-post
            </label>
            <input
              id="email-pw"
              name="email"
              type="email"
              inputMode="email"
              autoComplete="email"
              autoFocus
              placeholder="deg@eksempel.no"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              className={cn(inputBase, "border-clubhouse-border")}
            />
          </div>

          <div className="mt-4">
            <label htmlFor={pwIds} className="mb-1.5 block text-[0.9375rem] font-semibold text-clubhouse-ink">
              Passord
            </label>
            <div className="relative">
              <input
                id={pwIds}
                name="password"
                type={showPassword ? "text" : "password"}
                autoComplete="current-password"
                placeholder="Passordet ditt"
                value={password}
                onChange={(e) => setPassword(e.target.value)}
                className={cn(inputBase, "border-clubhouse-border pr-14")}
              />
              <button
                type="button"
                onClick={() => setShowPassword((s) => !s)}
                aria-label={showPassword ? "Skjul passord" : "Vis passord"}
                aria-pressed={showPassword}
                className={cn(
                  "absolute right-1 top-1/2 flex size-11 -translate-y-1/2 items-center justify-center rounded-lg text-clubhouse-muted transition-colors hover:text-clubhouse-ink",
                  focusRing,
                )}
              >
                {showPassword ? <EyeOffIcon className="size-5" /> : <EyeIcon className="size-5" />}
              </button>
            </div>
          </div>

          <button type="submit" disabled={loading || !email.trim() || !password} className={cn(primaryBtn, "mt-6")}>
            {loading ? <Spinner className="size-5" /> : <KeyIcon className="size-5" />}
            {loading ? "Logger inn …" : "Logg inn"}
          </button>

          <div className="mt-6">
            <button type="button" className={backBtn} onClick={() => switchMode("email")}>
              <ArrowLeftIcon className="size-5" />
              Bruk innloggingslenke på e-post i stedet
            </button>
          </div>
        </form>
      )}

      {/* ---------- State 4: Join by code ---------- */}
      {mode === "code" && (
        <form onSubmit={handleJoin} noValidate>
          <h2 className="text-balance text-xl font-bold text-clubhouse-ink">Bli med via kode</h2>
          <p className="mt-1.5 text-pretty text-base leading-relaxed text-clubhouse-muted">
            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>

          {formError && <div className="mt-5">{<FormAlert>{formError}</FormAlert>}</div>}

          <div className="mt-5">
            <label htmlFor="invite" className="mb-1.5 block text-[0.9375rem] font-semibold text-clubhouse-ink">
              Invitasjonskode
            </label>
            <input
              id="invite"
              name="invite"
              type="text"
              autoFocus
              autoCapitalize="characters"
              autoCorrect="off"
              spellCheck={false}
              enterKeyHint="go"
              placeholder="F.EKS. RYDER-25"
              value={code}
              onChange={(e) => setCode(e.target.value.toUpperCase())}
              className={cn(inputBase, "border-clubhouse-border font-mono tracking-[0.15em] uppercase")}
            />
          </div>

          <button type="submit" disabled={loading || !code.trim()} className={cn(primaryBtn, "mt-6")}>
            {loading ? <Spinner className="size-5" /> : <FlagIcon className="size-5" />}
            {loading ? "Sjekker …" : "Gå til turnering"}
          </button>

          <div className="mt-6">
            <button type="button" className={backBtn} onClick={() => switchMode("email")}>
              <ArrowLeftIcon className="size-5" />
              Tilbake til innlogging
            </button>
          </div>
        </form>
      )}
    </div>
  )
}
