"use client"

import { useEffect, useRef, useState } from "react"
import {
  Building2,
  Check,
  Globe,
  Loader2,
  TriangleAlert,
  Users,
} from "lucide-react"

import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Switch } from "@/components/ui/switch"

export type TournamentSettingsValues = {
  name: string
  startDate: string | null // "YYYY-MM-DD", or null if not set
  endDate: string | null // "YYYY-MM-DD", or null if not set
  visibility: "public" | "org" | "participants"
  description: string // "" if empty, never null
  registrationDeadline: string | null // ISO datetime ("YYYY-MM-DDTHH:mm"), or null
  registrationCapacity: number | null // null = uncapped
  registrationOverflowPolicy: "waitlist" | "closed" // only meaningful once a capacity is set
  registrationRequiresApproval: boolean
}

const VISIBILITY_OPTIONS: {
  value: TournamentSettingsValues["visibility"]
  label: string
  description: string
  icon: typeof Globe
}[] = [
  {
    value: "public",
    label: "Offentlig",
    description: "Hvem som helst kan finne turneringen.",
    icon: Globe,
  },
  {
    value: "org",
    label: "Organisasjonen",
    description: "Bare medlemmer av organisasjonen din.",
    icon: Building2,
  },
  {
    value: "participants",
    label: "Kun deltakere",
    description: "Bare de som allerede er påmeldt.",
    icon: Users,
  },
]

const inputBase =
  "h-11 w-full rounded-xl border border-border bg-background px-3 text-base text-foreground shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50"

export function TournamentSettingsCard({
  values,
  onSave,
}: {
  values: TournamentSettingsValues
  onSave: (next: TournamentSettingsValues) => Promise<void>
}) {
  const [draft, setDraft] = useState<TournamentSettingsValues>(values)
  const [status, setStatus] = useState<"idle" | "saving" | "saved" | "error">("idle")
  const [errorMessage, setErrorMessage] = useState<string | null>(null)

  // Only re-sync the draft from props when the SAVED values genuinely change
  // (e.g. after a real save round-trip), never on an incidental parent
  // re-render that hands us a new object with identical contents.
  const lastSyncedRef = useRef<string>(JSON.stringify(values))
  useEffect(() => {
    const serialized = JSON.stringify(values)
    if (serialized !== lastSyncedRef.current) {
      lastSyncedRef.current = serialized
      setDraft(values)
    }
  }, [values])

  const savedFadeRef = useRef<ReturnType<typeof setTimeout> | null>(null)
  useEffect(() => {
    return () => {
      if (savedFadeRef.current) clearTimeout(savedFadeRef.current)
    }
  }, [])

  function patch<K extends keyof TournamentSettingsValues>(
    key: K,
    value: TournamentSettingsValues[K],
  ) {
    setDraft((prev) => ({ ...prev, [key]: value }))
    // Any edit clears a lingering "saved"/"error" indicator.
    setStatus((s) => (s === "saving" ? s : "idle"))
    setErrorMessage(null)
  }

  const nameEmpty = draft.name.trim() === ""
  const dirty = JSON.stringify(draft) !== JSON.stringify(values)
  const capacitySet = draft.registrationCapacity != null
  const saving = status === "saving"
  const canSave = dirty && !nameEmpty && !saving

  async function handleSave() {
    if (!canSave) return
    setStatus("saving")
    setErrorMessage(null)
    try {
      // Normalize: trim the name; overflow policy is irrelevant without a cap.
      const next: TournamentSettingsValues = {
        ...draft,
        name: draft.name.trim(),
      }
      await onSave(next)
      lastSyncedRef.current = JSON.stringify(next)
      setDraft(next)
      setStatus("saved")
      if (savedFadeRef.current) clearTimeout(savedFadeRef.current)
      savedFadeRef.current = setTimeout(() => setStatus("idle"), 2600)
    } catch (err) {
      setStatus("error")
      setErrorMessage(
        err instanceof Error ? err.message : "Kunne ikke lagre. Prøv igjen.",
      )
    }
  }

  return (
    <section
      aria-labelledby="tsc-heading"
      className="rounded-2xl border border-border bg-card p-5 shadow-md shadow-black/8 lg:p-7"
    >
      <header className="mb-6 flex flex-col gap-1">
        <h2 id="tsc-heading" className="text-xl font-bold text-foreground lg:text-2xl">
          Grunnleggende
        </h2>
        <p className="text-sm text-muted-foreground text-pretty">
          Navn, datoer, synlighet og påmelding for turneringen.
        </p>
      </header>

      <div className="grid grid-cols-1 gap-6 lg:grid-cols-2">
        {/* Navn — spans full width */}
        <div className="flex flex-col gap-2 lg:col-span-2">
          <Label htmlFor="tsc-name" className="text-base font-semibold text-foreground">
            Navn
          </Label>
          <Input
            id="tsc-name"
            value={draft.name}
            onChange={(e) => patch("name", e.target.value)}
            aria-required="true"
            aria-invalid={nameEmpty}
            aria-describedby={nameEmpty ? "tsc-name-error" : undefined}
            className="h-11 rounded-xl text-base"
            placeholder="F.eks. Klubbmesterskapet 2026"
          />
          {nameEmpty && (
            <p id="tsc-name-error" className="text-sm font-medium text-destructive">
              Navn er påkrevd.
            </p>
          )}
        </div>

        {/* Datoer — one connected range control */}
        <fieldset className="flex flex-col gap-2 lg:col-span-2">
          <legend className="mb-2 text-base font-semibold text-foreground">Datoer</legend>
          <div className="flex flex-col gap-3 sm:flex-row sm:items-end">
            <div className="flex flex-1 flex-col gap-1.5">
              <Label htmlFor="tsc-start" className="text-sm text-muted-foreground">
                Startdato
              </Label>
              <input
                id="tsc-start"
                type="date"
                value={draft.startDate ?? ""}
                max={draft.endDate ?? undefined}
                onChange={(e) => patch("startDate", e.target.value || null)}
                className={inputBase}
              />
            </div>
            <span
              aria-hidden="true"
              className="hidden shrink-0 pb-3 text-muted-foreground sm:block"
            >
              &ndash;
            </span>
            <div className="flex flex-1 flex-col gap-1.5">
              <Label htmlFor="tsc-end" className="text-sm text-muted-foreground">
                Sluttdato
              </Label>
              <input
                id="tsc-end"
                type="date"
                value={draft.endDate ?? ""}
                min={draft.startDate ?? undefined}
                onChange={(e) => patch("endDate", e.target.value || null)}
                className={inputBase}
              />
            </div>
          </div>
        </fieldset>

        {/* Synlighet — real radio group, spans full width */}
        <fieldset className="flex flex-col gap-3 lg:col-span-2">
          <legend className="text-base font-semibold text-foreground">Synlighet</legend>
          <div
            role="radiogroup"
            aria-label="Synlighet"
            className="grid grid-cols-1 gap-3 sm:grid-cols-3"
          >
            {VISIBILITY_OPTIONS.map((o) => {
              const selected = draft.visibility === o.value
              const Icon = o.icon
              return (
                <label
                  key={o.value}
                  className={cn(
                    "flex cursor-pointer flex-col gap-1.5 rounded-xl border p-4 transition-colors focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2 focus-within:ring-offset-background",
                    selected
                      ? "border-primary bg-primary/5 ring-1 ring-primary"
                      : "border-border bg-background hover:border-primary/50 hover:bg-accent/40",
                  )}
                >
                  <span className="flex items-center gap-2">
                    <input
                      type="radio"
                      name="tsc-visibility"
                      value={o.value}
                      checked={selected}
                      onChange={() => patch("visibility", o.value)}
                      className="size-5 shrink-0 accent-primary"
                    />
                    <Icon
                      aria-hidden="true"
                      className={cn(
                        "size-4 shrink-0",
                        selected ? "text-primary" : "text-muted-foreground",
                      )}
                    />
                    <span className="text-base font-bold text-foreground">{o.label}</span>
                  </span>
                  <span className="pl-7 text-sm leading-relaxed text-muted-foreground text-pretty">
                    {o.description}
                  </span>
                </label>
              )
            })}
          </div>
        </fieldset>

        {/* Beskrivelse — spans full width */}
        <div className="flex flex-col gap-2 lg:col-span-2">
          <Label htmlFor="tsc-desc" className="text-base font-semibold text-foreground">
            Beskrivelse
          </Label>
          <textarea
            id="tsc-desc"
            value={draft.description}
            onChange={(e) => patch("description", e.target.value)}
            rows={4}
            className="w-full rounded-xl border border-border bg-background px-3 py-2.5 text-base leading-relaxed text-foreground shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background"
            placeholder="Valgfri informasjon til deltakerne."
          />
        </div>

        {/* Påmelding — grouped inset panel, spans full width */}
        <fieldset className="rounded-2xl border border-border bg-background/60 p-4 lg:col-span-2 lg:p-5">
          <legend className="flex items-center gap-2 rounded-lg bg-card px-2 text-base font-bold text-foreground">
            Påmelding
          </legend>

          <div className="grid grid-cols-1 gap-5 lg:grid-cols-2">
            {/* Påmeldingsfrist */}
            <div className="flex flex-col gap-2">
              <Label htmlFor="tsc-deadline" className="text-base font-semibold text-foreground">
                Påmeldingsfrist
              </Label>
              <input
                id="tsc-deadline"
                type="datetime-local"
                value={draft.registrationDeadline ?? ""}
                onChange={(e) => patch("registrationDeadline", e.target.value || null)}
                className={inputBase}
              />
              <p className="text-sm text-muted-foreground">Valgfri. Tom = ingen frist.</p>
            </div>

            {/* Maks antall påmeldte */}
            <div className="flex flex-col gap-2">
              <Label htmlFor="tsc-capacity" className="text-base font-semibold text-foreground">
                Maks antall påmeldte
              </Label>
              <input
                id="tsc-capacity"
                type="number"
                inputMode="numeric"
                min={1}
                step={1}
                value={draft.registrationCapacity ?? ""}
                onChange={(e) => {
                  const v = e.target.value
                  if (v === "") return patch("registrationCapacity", null)
                  const n = Math.max(1, Math.floor(Number(v)))
                  patch("registrationCapacity", Number.isFinite(n) ? n : null)
                }}
                className={inputBase}
                placeholder="Ubegrenset"
              />
              <p className="text-sm text-muted-foreground">Tom = ubegrenset.</p>
            </div>

            {/* Når fullt — disabled + explained when no capacity */}
            <fieldset
              className="flex flex-col gap-3"
              disabled={!capacitySet}
              aria-describedby={!capacitySet ? "tsc-overflow-hint" : undefined}
            >
              <legend
                className={cn(
                  "text-base font-semibold",
                  capacitySet ? "text-foreground" : "text-muted-foreground",
                )}
              >
                Når fullt
              </legend>
              <div
                role="radiogroup"
                aria-label="Når fullt"
                className={cn("grid grid-cols-2 gap-2", !capacitySet && "opacity-50")}
              >
                {(
                  [
                    { value: "waitlist", label: "Venteliste" },
                    { value: "closed", label: "Stengt" },
                  ] as const
                ).map((o) => {
                  const selected = draft.registrationOverflowPolicy === o.value
                  return (
                    <label
                      key={o.value}
                      className={cn(
                        "flex min-h-11 cursor-pointer items-center justify-center gap-2 rounded-xl border px-3 text-base font-bold transition-colors focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2 focus-within:ring-offset-background",
                        !capacitySet && "cursor-not-allowed",
                        selected
                          ? "border-primary bg-primary text-primary-foreground"
                          : "border-border bg-card text-foreground hover:border-primary/50 hover:bg-accent/40",
                      )}
                    >
                      <input
                        type="radio"
                        name="tsc-overflow"
                        value={o.value}
                        checked={selected}
                        disabled={!capacitySet}
                        onChange={() => patch("registrationOverflowPolicy", o.value)}
                        className="sr-only"
                      />
                      {o.label}
                    </label>
                  )
                })}
              </div>
              {!capacitySet && (
                <p
                  id="tsc-overflow-hint"
                  className="flex items-center gap-1.5 text-sm font-medium text-muted-foreground"
                >
                  <TriangleAlert aria-hidden="true" className="size-4 shrink-0" />
                  Sett et maks-antall for å bruke dette.
                </p>
              )}
            </fieldset>

            {/* Krev godkjenning */}
            <div className="flex flex-col gap-2">
              <span className="text-base font-semibold text-foreground">Krev godkjenning</span>
              <label
                htmlFor="tsc-approval"
                className="flex min-h-11 cursor-pointer items-center justify-between gap-3 rounded-xl border border-border bg-card px-4 py-2"
              >
                <span className="text-sm leading-relaxed text-muted-foreground text-pretty">
                  {draft.registrationRequiresApproval
                    ? "Organisator må godkjenne hver påmelding manuelt."
                    : "Påmeldinger godkjennes automatisk."}
                </span>
                <Switch
                  id="tsc-approval"
                  checked={draft.registrationRequiresApproval}
                  onCheckedChange={(checked) =>
                    patch("registrationRequiresApproval", checked === true)
                  }
                  aria-label="Krev godkjenning av påmeldinger"
                />
              </label>
            </div>
          </div>
        </fieldset>
      </div>

      {/* Save row */}
      <div className="mt-7 flex flex-wrap items-center gap-3 border-t border-border pt-5">
        <Button
          type="button"
          onClick={handleSave}
          disabled={!canSave}
          className="h-11 rounded-xl px-6 text-base font-bold"
        >
          {saving && <Loader2 aria-hidden="true" className="size-4 animate-spin" />}
          {saving ? "Lagrer…" : "Lagre"}
        </Button>

        {status === "saved" && (
          <span
            role="status"
            className="flex animate-in fade-in items-center gap-1.5 text-sm font-bold text-primary duration-300"
          >
            <Check aria-hidden="true" className="size-4" />
            Lagret
          </span>
        )}

        {status === "error" && errorMessage && (
          <span role="alert" className="flex items-center gap-1.5 text-sm font-bold text-destructive">
            <TriangleAlert aria-hidden="true" className="size-4" />
            {errorMessage}
          </span>
        )}

        {!dirty && status === "idle" && (
          <span className="text-sm text-muted-foreground">Ingen ulagrede endringer.</span>
        )}
      </div>
    </section>
  )
}
