"use client"

import { useEffect, useRef, useState } from "react"
import { Loader2, TriangleAlert } from "lucide-react"
import { cn } from "@/lib/utils"

// V0-generert (ADR-093, 2026-08-19) -- ren kontrollert/presentasjonell
// komponent, ingen egne fetch-kall. SetupTab (individual-tournament-
// detail.tsx) eier all datahenting/orkestrering og sender ferdig
// sammenslått data + callback-props inn.

export type RoundParticipationPlayer = {
  participantId: string
  playerId: string
  name: string
  gender: "m" | "f" | "x" | null
  birthDate: string | null // ISO "YYYY-MM-DD", null if unknown
}

export type RoundParticipationRound = {
  id: string
  label: string // e.g. "Runde 1"
  tees: { id: string; name: string }[] // this round's course's available tees
}

export type RoundParticipationCell = {
  assigned: boolean
  teeId: string | null // null when not assigned
  teeName: string | null
}

export type RoundParticipationTableProps = {
  players: RoundParticipationPlayer[]
  rounds: RoundParticipationRound[]
  // cells[roundId][participantId]
  cells: Record<string, Record<string, RoundParticipationCell>>
  onToggle: (roundId: string, participantId: string, checked: boolean, teeId: string) => void
  onBulkToggle: (roundId: string, checked: boolean, teeId: string) => void
  onChangeTee: (roundId: string, participantId: string, teeId: string) => void
  onChangeGender: (playerId: string, gender: "m" | "f" | "x") => void
  onChangeBirthDate: (playerId: string, birthDate: string) => void
  busyRoundIds: string[]
  errors: string[]
}

// Standard age-from-birthdate: subtract years, then step back one if this
// year's birthday hasn't happened yet.
function computeAge(birthDate: string): number {
  const birth = new Date(birthDate)
  const now = new Date()
  let age = now.getFullYear() - birth.getFullYear()
  const monthDiff = now.getMonth() - birth.getMonth()
  if (monthDiff < 0 || (monthDiff === 0 && now.getDate() < birth.getDate())) {
    age -= 1
  }
  return age
}

const selectClass =
  "h-10 rounded-lg border border-border bg-background px-2 text-sm font-medium text-foreground transition-all duration-200 ease-in-out hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"

export function RoundParticipationTable({
  players,
  rounds,
  cells,
  onToggle,
  onBulkToggle,
  onChangeTee,
  onChangeGender,
  onChangeBirthDate,
  busyRoundIds,
  errors,
}: RoundParticipationTableProps) {
  // Local-only convenience state: each round column's "Standardutslag"
  // selection, used to pre-fill the teeId when checking a box. Resets to each
  // round's first tee on mount / when the round set changes.
  const [defaultTees, setDefaultTees] = useState<Record<string, string>>(() =>
    Object.fromEntries(rounds.map((r) => [r.id, r.tees[0]?.id ?? ""])),
  )

  useEffect(() => {
    setDefaultTees((prev) => {
      const next: Record<string, string> = {}
      for (const r of rounds) {
        // keep an existing valid selection, otherwise fall back to first tee
        const existing = prev[r.id]
        const stillValid = existing && r.tees.some((t) => t.id === existing)
        next[r.id] = stillValid ? existing : (r.tees[0]?.id ?? "")
      }
      return next
    })
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [rounds.map((r) => r.id + ":" + r.tees.map((t) => t.id).join(",")).join("|")])

  return (
    <div className="flex flex-col gap-4">
      {errors.length > 0 && (
        <div
          role="alert"
          className="flex flex-col gap-1.5 rounded-2xl border border-destructive/30 bg-destructive/10 p-4"
        >
          <div className="flex items-center gap-2 font-bold text-destructive">
            <TriangleAlert aria-hidden="true" className="size-5 shrink-0" />
            <span>Noen endringer feilet</span>
          </div>
          <ul className="flex flex-col gap-1 pl-7 text-sm text-destructive">
            {errors.map((msg, i) => (
              <li key={i} className="text-pretty leading-relaxed">
                {msg}
              </li>
            ))}
          </ul>
        </div>
      )}

      <div className="overflow-x-auto rounded-2xl border border-border bg-card shadow-md shadow-black/8">
        <table className="w-full border-collapse text-left">
          <thead>
            <tr className="divide-x divide-border border-b border-border">
              <th
                scope="col"
                className="sticky left-0 z-20 min-w-48 bg-card px-4 py-3 align-bottom text-sm font-bold text-foreground"
              >
                Spiller
              </th>
              <th scope="col" className="min-w-32 bg-card px-3 py-3 align-bottom text-sm font-bold text-foreground">
                Kjønn
              </th>
              <th scope="col" className="min-w-56 bg-card px-3 py-3 align-bottom text-sm font-bold text-foreground">
                Alder
              </th>
              {rounds.map((round) => {
                const busy = busyRoundIds.includes(round.id)
                return (
                  <th
                    key={round.id}
                    scope="col"
                    className="min-w-56 bg-card px-3 py-3 align-bottom"
                  >
                    <div className="flex flex-col gap-2">
                      <div className="flex items-center gap-2">
                        <span className="text-sm font-bold text-foreground">{round.label}</span>
                        {busy && (
                          <span className="inline-flex items-center gap-1 text-xs font-semibold text-muted-foreground">
                            <Loader2 aria-hidden="true" className="size-3.5 animate-spin" />
                            Oppdaterer
                          </span>
                        )}
                      </div>
                      <div className="flex flex-col gap-2">
                        <label className="flex flex-col gap-1">
                          <span className="text-xs font-medium text-muted-foreground">Standardutslag</span>
                          <select
                            value={defaultTees[round.id] ?? ""}
                            disabled={busy}
                            onChange={(e) =>
                              setDefaultTees((prev) => ({ ...prev, [round.id]: e.target.value }))
                            }
                            className={selectClass}
                            aria-label={`Standardutslag for ${round.label}`}
                          >
                            {round.tees.map((tee) => (
                              <option key={tee.id} value={tee.id}>
                                {tee.name}
                              </option>
                            ))}
                          </select>
                        </label>
                        <BulkToggle
                          round={round}
                          players={players}
                          cells={cells}
                          busy={busy}
                          onBulkToggle={(checked) =>
                            onBulkToggle(round.id, checked, defaultTees[round.id] ?? "")
                          }
                        />
                      </div>
                    </div>
                  </th>
                )
              })}
            </tr>
          </thead>
          <tbody className="divide-y divide-border">
            {players.map((player) => {
              const age = player.birthDate ? computeAge(player.birthDate) : null
              return (
                <tr key={player.participantId} className="divide-x divide-border">
                  <th
                    scope="row"
                    className="sticky left-0 z-10 bg-card px-4 py-3 text-left font-bold text-foreground"
                  >
                    {player.name}
                  </th>

                  {/* Kjønn */}
                  <td className="px-3 py-3">
                    <select
                      value={player.gender ?? ""}
                      onChange={(e) => onChangeGender(player.playerId, e.target.value as "m" | "f" | "x")}
                      className={cn(selectClass, "w-full", player.gender === null && "text-muted-foreground")}
                      aria-label={`Kjønn for ${player.name}`}
                    >
                      <option value="" disabled>
                        Ikke satt
                      </option>
                      <option value="m">Mann</option>
                      <option value="f">Kvinne</option>
                      <option value="x">Annet</option>
                    </select>
                  </td>

                  {/* Alder */}
                  <td className="px-3 py-3">
                    <div className="flex items-center gap-2">
                      <input
                        type="date"
                        value={player.birthDate ?? ""}
                        onChange={(e) => onChangeBirthDate(player.playerId, e.target.value)}
                        className={cn(selectClass, "w-36")}
                        aria-label={`Fødselsdato for ${player.name}`}
                      />
                      <span className="shrink-0 text-sm tabular-nums text-muted-foreground">
                        {age !== null ? `${age} år` : "Ukjent"}
                      </span>
                    </div>
                  </td>

                  {/* Round columns */}
                  {rounds.map((round) => {
                    const busy = busyRoundIds.includes(round.id)
                    const cell = cells[round.id]?.[player.participantId]
                    const assigned = cell?.assigned ?? false
                    const cellId = `cell-${round.id}-${player.participantId}`
                    return (
                      <td key={round.id} className="px-3 py-3">
                        <div className="flex items-center gap-2">
                          <label
                            htmlFor={cellId}
                            className={cn(
                              "inline-flex min-h-10 cursor-pointer items-center gap-2 rounded-lg px-2 transition-all duration-200 ease-in-out hover:bg-accent",
                              busy && "pointer-events-none opacity-50",
                            )}
                          >
                            <input
                              id={cellId}
                              type="checkbox"
                              checked={assigned}
                              disabled={busy}
                              onChange={(e) =>
                                onToggle(
                                  round.id,
                                  player.participantId,
                                  e.target.checked,
                                  e.target.checked ? (defaultTees[round.id] ?? "") : (cell?.teeId ?? ""),
                                )
                              }
                              className="size-5 shrink-0 rounded border-border text-primary transition-all duration-200 ease-in-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
                            />
                            <span className="text-sm font-medium text-foreground">
                              {assigned ? "Spiller" : "Ikke satt"}
                            </span>
                          </label>

                          {assigned && (
                            <select
                              value={cell?.teeId ?? ""}
                              disabled={busy}
                              onChange={(e) => onChangeTee(round.id, player.participantId, e.target.value)}
                              className={selectClass}
                              aria-label={`Utslagssted for ${player.name} i ${round.label}`}
                            >
                              {round.tees.map((tee) => (
                                <option key={tee.id} value={tee.id}>
                                  {tee.name}
                                </option>
                              ))}
                            </select>
                          )}
                        </div>
                      </td>
                    )
                  })}
                </tr>
              )
            })}
          </tbody>
        </table>
      </div>
    </div>
  )
}

function BulkToggle({
  round,
  players,
  cells,
  busy,
  onBulkToggle,
}: {
  round: RoundParticipationRound
  players: RoundParticipationPlayer[]
  cells: Record<string, Record<string, RoundParticipationCell>>
  busy: boolean
  onBulkToggle: (checked: boolean) => void
}) {
  const ref = useRef<HTMLInputElement>(null)
  const assignedCount = players.reduce(
    (acc, p) => acc + (cells[round.id]?.[p.participantId]?.assigned ? 1 : 0),
    0,
  )
  const total = players.length
  const allAssigned = total > 0 && assignedCount === total
  const someAssigned = assignedCount > 0 && assignedCount < total

  useEffect(() => {
    if (ref.current) ref.current.indeterminate = someAssigned
  }, [someAssigned])

  const id = `bulk-${round.id}`
  return (
    <label
      htmlFor={id}
      className={cn(
        "inline-flex min-h-10 cursor-pointer items-center gap-2 rounded-lg px-2 transition-all duration-200 ease-in-out hover:bg-accent",
        busy && "pointer-events-none opacity-50",
      )}
    >
      <input
        id={id}
        ref={ref}
        type="checkbox"
        checked={allAssigned}
        disabled={busy}
        onChange={() => onBulkToggle(!allAssigned)}
        className="size-5 shrink-0 rounded border-border text-primary transition-all duration-200 ease-in-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
      />
      <span className="text-sm font-semibold text-foreground">
        {allAssigned ? "Velg ingen" : "Velg alle"}
      </span>
    </label>
  )
}

