import type React from "react"
import Link from "next/link"
import { ChevronRight, Gauge, MapPin, Medal, Trophy } from "lucide-react"
import { cn } from "@/lib/utils"

export type RoundStatus = "active" | "completed"

export type Round = {
  id: string
  name?: string | null
  courseName: string
  status: RoundStatus
  teeName: string
  holes: 9 | 18
  date: string
  playerCount: number
  // Progress for rounds still in play.
  holesPlayed?: number
  // Owner's score, present once at least one hole is recorded.
  totalScore?: number
  toPar?: number
  // Netto til-par (2026-07-29) -- kun slagspill, kun når HCP faktisk
  // spores for spilleren (samme betingelse som differensial-chipen).
  netToPar?: number
  // To-sidede formater (match/fourball/foursome/greensome/scramble,
  // 2026-07-29): VIEWER-relativ løpende status ("1 UP"/"AS"/"Vunnet 2&1"),
  // aldri backend sin bokstavelige side A/B. matchLead sitt fortegn (>0 =
  // spilleren leder) styrer fargen -- unngår å måtte parse teksten.
  playFormat?: string
  matchStatus?: string | null
  matchLead?: number | null
  // Handicap differential, only when a completed round counted (one decimal).
  differential?: number | null
  // Lowest score-to-par among the viewer's own completed rounds (computed
  // by the caller across the full rounds list, not by the card itself).
  isPersonalBest?: boolean
}

const STATUS_CONFIG: Record<RoundStatus, { label: string }> = {
  active: { label: "Pågår" },
  completed: { label: "Fullført" },
}

// Egen lokal kopi per prosjektets konvensjon (liten duplisering fremfor
// cross-file-import, se samme mønster i round-detail.tsx/round-scorecard.tsx).
const FORMAT_LABELS: Record<string, string> = {
  stroke: "Slagspill",
  stableford: "Stableford",
  match: "Match",
  skins: "Skins",
  fourball: "Fourball",
  foursome: "Foursome",
  greensome: "Greensome",
  scramble_2: "Scramble (2)",
  scramble_4: "Scramble (4)",
  chapman: "Chapman",
  copenhagen: "Københavner",
  bbb: "Bingo Bango Bongo",
  flag: "Flaggturnering",
  shamble: "Shamble",
  money_ball: "Money Ball",
  high_low_high: "High-low-high",
  scramble_solo: "Scramble mot enkeltspiller",
  scramble_solo_match: "Scramble mot enkeltspiller (matchspill)",
}

const dateFormatter = new Intl.DateTimeFormat("no-NO", {
  day: "numeric",
  month: "short",
  year: "numeric",
})

function formatDate(value: string) {
  const parsed = new Date(value)
  if (Number.isNaN(parsed.getTime())) return value
  return dateFormatter.format(parsed)
}

// "+10", "-2" or "E" for level par. The sign carries the meaning (never color alone).
function formatToPar(toPar: number) {
  if (toPar === 0) return "E"
  return toPar > 0 ? `+${toPar}` : `${toPar}`
}

function toParDescription(toPar: number) {
  if (toPar === 0) return "på par"
  return toPar > 0 ? `${toPar} over par` : `${Math.abs(toPar)} under par`
}

// Status vises nå som fet, farget tekst (samme "form+farge, aldri farge
// alene"-prinsipp -- teksten SIER "Pågår"/"Fullført", fargen er kun en
// forsterkning) i stedet for en pille-badge, for en tettere,
// nøkkel/verdi-orientert korttype.
const STATUS_TEXT_CLASS: Record<RoundStatus, string> = {
  active: "text-primary",
  completed: "text-brand-orange",
}

function RoundProgressBar({ played, holes }: { played: number; holes: number }) {
  const pct = holes > 0 ? Math.min(100, Math.round((played / holes) * 100)) : 0
  return (
    <div
      className="h-1.5 w-full overflow-hidden rounded-full bg-border"
      role="progressbar"
      aria-valuenow={played}
      aria-valuemin={0}
      aria-valuemax={holes}
      aria-label={`${played} av ${holes} hull spilt`}
    >
      <div className="h-full rounded-full bg-primary" style={{ width: `${pct}%` }} />
    </div>
  )
}

// Kompakt nøkkel/verdi-celle -- selve rammen for grid-strukturen under
// tittelen (label liten/dempet over, verdi stor/fet under).
function InfoCell({
  label,
  value,
  valueClassName,
}: {
  label: string
  value: React.ReactNode
  valueClassName?: string
}) {
  return (
    <div className="flex flex-col gap-0.5">
      <span className="text-xs font-medium uppercase tracking-wide text-muted-foreground">{label}</span>
      <span className={cn("text-base font-bold tabular-nums text-foreground", valueClassName)}>{value}</span>
    </div>
  )
}

export function RoundCard({ round }: { round: Round }) {
  const playerLabel = round.playerCount === 1 ? "spiller" : "spillere"
  const hasScore = typeof round.totalScore === "number" && typeof round.toPar === "number"
  const showDifferential =
    round.status === "completed" &&
    typeof round.differential === "number" &&
    round.differential !== null
  const differentialText =
    showDifferential && round.differential != null
      ? round.differential.toFixed(1).replace(".", ",")
      : null
  const showPersonalBest = round.status === "completed" && round.isPersonalBest === true
  // Skjules for "stroke" (samme "kun avvik fra standardformatet er verdt en
  // pille"-konvensjon som round-scorecard.tsx sin sammendrags-stripe).
  const formatLabel = round.playFormat && round.playFormat !== "stroke" ? FORMAT_LABELS[round.playFormat] ?? round.playFormat : null

  // To-sidede formater (match/fourball/foursome/greensome/scramble,
  // 2026-07-29): vis matchStatus i stedet for rå slagtall -- brutto
  // slagtotal alene sier lite i matchspill. Alltid VIEWER-relativ tekst
  // (aldri backend sin bokstavelige side A/B), samme kilde uansett om
  // runden pågår eller er fullført (bruker bekreftet begge).
  const hasMatchStatus = typeof round.matchStatus === "string" && round.matchStatus.length > 0
  const matchLead = round.matchLead ?? 0
  const matchStatusClassName = matchLead > 0 ? "text-primary" : matchLead < 0 ? "text-brand-orange" : ""

  // Concise summary so the compact score tile reads clearly for screen readers.
  const scoreSummary = hasMatchStatus
    ? `Resultat ${round.matchStatus}.`
    : hasScore
      ? `Resultat ${round.totalScore} slag, ${toParDescription(round.toPar as number)}.`
      : `${round.holesPlayed ?? 0} av ${round.holes} hull spilt.`
  const displayTitle = round.name?.trim() || round.courseName
  const ariaLabel = `${displayTitle}, ${STATUS_CONFIG[round.status].label}. ${scoreSummary}`

  const played = round.holesPlayed ?? 0
  // Resultat vises nå BÅDE mens runden pågår og etter fullføring (2026-07-29,
  // bekreftet av bruker) -- ikke lenger gatet til kun fullførte runder.
  const showResultRow = !hasMatchStatus && hasScore
  const toPar = round.toPar as number | undefined
  const toParClassName = toPar === undefined ? "" : toPar > 0 ? "text-brand-orange" : toPar < 0 ? "text-primary" : ""
  const netToPar = round.netToPar
  const netToParClassName = netToPar === undefined ? "" : netToPar > 0 ? "text-brand-orange" : netToPar < 0 ? "text-primary" : ""

  return (
    // Egen ytre wrapper (2026-07-26) -- kortet var tidligere HELE selve
    // lenken til rundesiden; en leaderboard-lenke kan derfor ikke ligge
    // NESTET inni den (ugyldig HTML, samme klasse feil som tidligere
    // nestede-form-/knapp-feller i prosjektet). Hovedinnholdet er fortsatt
    // én stor lenke til rundesiden, leaderboard-lenken en egen, separat
    // rad under.
    <div className="flex flex-col gap-2">
      <Link
        href={`/my-rounds/${round.id}`}
        aria-label={ariaLabel}
        className="group flex w-full flex-col gap-3 rounded-2xl border border-border bg-card p-4 text-left shadow-md shadow-black/8 transition-all duration-200 ease-in-out hover:border-primary/60 hover:bg-accent/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background sm:p-5"
      >
        <div className="flex items-start justify-between gap-3">
          <div className="flex min-w-0 flex-col">
            <h3 className="flex min-w-0 items-center gap-2 text-lg font-bold text-foreground">
              <MapPin aria-hidden="true" className="size-5 shrink-0 text-primary" />
              <span className="truncate">{displayTitle}</span>
            </h3>
            {round.name?.trim() && (
              <span className="truncate pl-7 text-sm text-muted-foreground">{round.courseName}</span>
            )}
          </div>
          <ChevronRight
            aria-hidden="true"
            className="size-6 shrink-0 text-muted-foreground transition-transform group-hover:translate-x-0.5 group-hover:text-foreground"
          />
        </div>

        <div className="flex flex-wrap items-center justify-between gap-2">
          <span className="flex items-center gap-2">
            <span className={cn("text-sm font-bold", STATUS_TEXT_CLASS[round.status])}>
              {STATUS_CONFIG[round.status].label}
            </span>
            {formatLabel && (
              <span className="rounded-full bg-muted px-2 py-0.5 text-xs font-bold text-muted-foreground">
                {formatLabel}
              </span>
            )}
          </span>
          {/* Vis "spilt av planlagt" når det faktisk AVVIKER fra planen --
              ikke bare mens runden pågår. En runde markert Fullført etter
              f.eks. 9 av 18 planlagte hull skal fortsatt vise det avviket
              her, ikke bare stille bytte til status-teksten (2026-08-11,
              reelt funn: "Hull"-cellen under viser uansett kun PLANLAGT
              antall, aldri hvor mange som faktisk ble spilt). */}
          {played < round.holes && (
            <span className="text-xs font-semibold tabular-nums text-muted-foreground">
              {played}/{round.holes} hull spilt
            </span>
          )}
          {showPersonalBest && (
            <span className="inline-flex items-center gap-1.5 rounded-full bg-gold/20 px-2.5 py-1 text-xs font-bold text-foreground">
              <Medal aria-hidden="true" className="size-3.5 text-gold" />
              Personlig rekord
            </span>
          )}
        </div>
        {round.status === "active" && <RoundProgressBar played={played} holes={round.holes} />}

        <div className="grid grid-cols-2 gap-x-4 gap-y-3 border-t border-border pt-3">
          <InfoCell label="Tee" value={round.teeName} />
          <InfoCell label="Hull" value={round.holes} />
          <InfoCell label="Dato" value={formatDate(round.date)} />
          <InfoCell label="Spillere" value={`${round.playerCount} ${playerLabel}`} />
          {hasMatchStatus && (
            <InfoCell label="Resultat" value={round.matchStatus} valueClassName={cn("text-lg", matchStatusClassName)} />
          )}
          {showResultRow && (
            <>
              <InfoCell label="Resultat" value={round.totalScore} valueClassName="text-lg" />
              <InfoCell label="Til par" value={formatToPar(toPar as number)} valueClassName={cn("text-lg", toParClassName)} />
              {netToPar !== undefined && (
                <InfoCell label="Netto" value={formatToPar(netToPar)} valueClassName={cn("text-lg", netToParClassName)} />
              )}
            </>
          )}
        </div>

        {differentialText && (
          <span className="inline-flex w-fit items-center gap-1.5 rounded-full bg-info/15 px-2.5 py-0.5 text-sm font-semibold text-foreground">
            <Gauge aria-hidden="true" className="size-4 shrink-0 text-info" />
            <span className="tabular-nums">Hcp spilt til {differentialText}</span>
          </span>
        )}
      </Link>

      {/* Leaderboard-lenke (2026-07-26) -- kun meningsfullt med flere enn
          én deltaker. Vises for BÅDE pågående og fullførte runder (en
          fullført rundes sluttstilling er fortsatt nyttig å se). */}
      {round.playerCount > 1 && (
        <Link
          href={`/my-rounds/${round.id}/leaderboard`}
          className="flex min-h-11 items-center gap-1.5 self-start rounded-xl px-4 text-sm font-semibold text-primary transition-colors hover:bg-primary/10"
        >
          <Trophy aria-hidden="true" className="size-4" />
          Se leaderboard
        </Link>
      )}
    </div>
  )
}
