"use client"

// V0-eksportert visning (2026-08-17, ADR-083) -- ren kontrollert
// komponent, ingen egen GPS-/geometrilogikk. All geometri-utregning
// (projectOntoAxis) bor i hole-target-distance.tsx, allerede bevist
// riktig med enhetstester + scratch-verifisering FØR denne visningen
// ble bestilt. Erstattet en midlertidig hånd-kodet stand-in med samme
// props-kontrakt -- samme mønster som FlagPlantSheet/PlayerImportPanel.

import { Flag, MapPin, TriangleAlert } from "lucide-react"
import { cn } from "@/lib/utils"

export type DiagramHazard = {
  label: string
  /** Live distance FROM THE PLAYER, always accurate. */
  distanceMeters: number
  /** 0 = at tee, 100 = at green. May be <0 or >100. */
  alongPercent: number
  /** Positive = right of the tee->green axis, negative = left. */
  crossMeters: number
}

type Props = {
  distances: { front: number; middle: number; back: number }
  playerPosition: { alongPercent: number; crossMeters: number }
  /** Already sorted nearest-to-player first. */
  hazards: DiagramHazard[]
  size?: "compact" | "full"
  className?: string
}

// --- Diagram geometry (percentages of the field box) ---------------------
// Fixed endpoints: green stays at the top, tee stays at the bottom, always.
const TRACK_TOP = 12 // where alongPercent === 100 lands (leaves room for the flag)
const TRACK_BOTTOM = 88 // where alongPercent === 0 lands (leaves room for the tee dot)
// Sideways scale: this many meters of cross offset maps to the max visual swing.
const MAX_CROSS_METERS = 30
const MAX_OFFSET_PCT = 40 // ±40% of the field width, per spec
// Label collision handling: minimum vertical gap between stacked labels.
const LABEL_MIN_GAP_PCT = 11

function clamp(n: number, lo: number, hi: number) {
  return Math.min(hi, Math.max(lo, n))
}

function alongToTopPct(alongPercent: number) {
  const a = clamp(alongPercent, 0, 100)
  return TRACK_TOP + ((100 - a) / 100) * (TRACK_BOTTOM - TRACK_TOP)
}

function crossToLeftPct(crossMeters: number) {
  const offset = clamp(
    (crossMeters / MAX_CROSS_METERS) * MAX_OFFSET_PCT,
    -MAX_OFFSET_PCT,
    MAX_OFFSET_PCT,
  )
  return 50 + offset
}

function formatMeters(m: number) {
  return `${Math.round(m)} m`
}

export function HoleDiagram({
  distances,
  playerPosition,
  hazards,
  size = "full",
  className,
}: Props) {
  if (size === "compact") {
    return (
      <div
        className={cn(
          "flex flex-col gap-2 rounded-xl border border-clubhouse-border bg-clubhouse-card p-3 text-clubhouse-ink",
          className,
        )}
      >
        <div className="flex items-baseline justify-center gap-3 tabular-nums">
          <CompactNumber label="Front" value={distances.front} />
          <CompactNumber label="Senter" value={distances.middle} emphasized />
          <CompactNumber label="Bak" value={distances.back} />
        </div>
        {hazards.length > 0 && (
          <ul className="flex flex-col gap-1 border-t border-clubhouse-border pt-2">
            {hazards.map((h, i) => (
              <li key={`${h.label}-${i}`} className="flex items-center gap-1.5 text-sm">
                <TriangleAlert
                  aria-hidden="true"
                  className="size-3.5 shrink-0 text-cup-strong"
                />
                <span className="min-w-0 flex-1 truncate text-clubhouse-muted">{h.label}</span>
                <span className="shrink-0 font-bold tabular-nums text-clubhouse-ink">
                  {formatMeters(h.distanceMeters)}
                </span>
              </li>
            ))}
          </ul>
        )}
      </div>
    )
  }

  // --- Full variant -------------------------------------------------------
  // Precompute placements and a light label-collision nudge (top -> bottom).
  const placed = hazards.map((h, i) => ({
    ...h,
    key: `${h.label}-${i}`,
    topPct: alongToTopPct(h.alongPercent),
    leftPct: crossToLeftPct(h.crossMeters),
  }))

  const byTop = [...placed].sort((a, b) => a.topPct - b.topPct)
  const labelTopByKey = new Map<string, number>()
  let lastLabelTop = Number.NEGATIVE_INFINITY
  for (const p of byTop) {
    const desired = p.topPct
    const labelTop = Math.max(desired, lastLabelTop + LABEL_MIN_GAP_PCT)
    labelTopByKey.set(p.key, labelTop)
    lastLabelTop = labelTop
  }

  const playerTop = alongToTopPct(playerPosition.alongPercent)
  const playerLeft = crossToLeftPct(playerPosition.crossMeters)

  return (
    <div className={cn("flex w-full flex-col gap-4 text-clubhouse-ink", className)}>
      {/* Distance readout: center emphasized + largest, in the tee-green color. */}
      <div className="flex items-end justify-center gap-6 tabular-nums">
        <BigNumber label="Front" value={distances.front} />
        <BigNumber label="Senter" value={distances.middle} emphasized />
        <BigNumber label="Bak" value={distances.back} />
      </div>

      {/* The hole diagram. Green fixed top, tee fixed bottom. */}
      <div
        className="relative h-[24rem] w-full overflow-hidden rounded-2xl border border-clubhouse-border bg-clubhouse-field"
        role="img"
        aria-label={buildDiagramAria(distances, hazards, playerPosition)}
      >
        {/* Discreet tee->green centerline */}
        <div
          aria-hidden="true"
          className="absolute top-[10%] bottom-[10%] left-1/2 w-px -translate-x-1/2 bg-clubhouse-border"
        />

        {/* Green marker (fixed top) */}
        <div
          aria-hidden="true"
          className="absolute left-1/2 top-[3%] flex -translate-x-1/2 flex-col items-center gap-0.5"
        >
          <Flag className="size-6 text-tee-strong" strokeWidth={2.5} />
          <span className="rounded bg-clubhouse-card px-1.5 py-0.5 text-xs font-bold text-tee-strong">
            Green
          </span>
        </div>

        {/* Tee marker (fixed bottom) */}
        <div
          aria-hidden="true"
          className="absolute bottom-[3%] left-1/2 flex -translate-x-1/2 flex-col items-center gap-0.5"
        >
          <span className="rounded bg-clubhouse-card px-1.5 py-0.5 text-xs font-bold text-clubhouse-muted">
            Tee
          </span>
          <span className="size-3 rounded-full border-2 border-clubhouse-muted bg-clubhouse-card" />
        </div>

        {/* Hazard markers + always-visible distance labels */}
        {placed.map((p) => {
          const labelTop = labelTopByKey.get(p.key) ?? p.topPct
          const labelOnLeft = p.leftPct > 55
          return (
            <div key={p.key} aria-hidden="true">
              {/* marker dot */}
              <div
                className="absolute z-10 flex size-7 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-full border-2 border-clubhouse-card bg-cup-strong shadow-sm"
                style={{ top: `${p.topPct}%`, left: `${p.leftPct}%` }}
              >
                <TriangleAlert className="size-4 text-clubhouse-card" strokeWidth={2.5} />
              </div>
              {/* distance label (nudged vertically on collision) */}
              <div
                className={cn(
                  "absolute z-20 -translate-y-1/2 whitespace-nowrap rounded-md bg-clubhouse-card px-1.5 py-0.5 text-xs font-bold tabular-nums text-clubhouse-ink shadow-sm ring-1 ring-clubhouse-border",
                  labelOnLeft ? "-translate-x-full" : "translate-x-0",
                )}
                style={{
                  top: `${labelTop}%`,
                  left: labelOnLeft ? `calc(${p.leftPct}% - 1rem)` : `calc(${p.leftPct}% + 1rem)`,
                }}
              >
                {formatMeters(p.distanceMeters)}
              </div>
            </div>
          )
        })}

        {/* Player position ("you are here") — a pin, shape-distinct from hazards */}
        <div
          aria-hidden="true"
          className="absolute z-30 flex -translate-x-1/2 -translate-y-full flex-col items-center"
          style={{ top: `${playerTop}%`, left: `${playerLeft}%` }}
        >
          <span className="mb-0.5 rounded bg-clubhouse-card px-1.5 py-0.5 text-xs font-bold text-tee-strong ring-1 ring-clubhouse-border">
            Deg
          </span>
          <MapPin className="size-7 fill-tee-strong text-clubhouse-card" strokeWidth={2} />
        </div>
      </div>

      {/* Accessible, screen-reader-friendly text list — the same info as the diagram. */}
      {hazards.length > 0 && (
        <div className="flex flex-col gap-2">
          <h3 className="text-sm font-bold uppercase tracking-wide text-clubhouse-muted">
            Hindringer
          </h3>
          <ul className="flex flex-col divide-y divide-clubhouse-border rounded-xl border border-clubhouse-border bg-clubhouse-card">
            {hazards.map((h, i) => (
              <li key={`${h.label}-${i}`} className="flex items-center gap-3 px-3 py-2.5">
                <TriangleAlert
                  aria-hidden="true"
                  className="size-5 shrink-0 text-cup-strong"
                  strokeWidth={2.5}
                />
                <span className="min-w-0 flex-1 text-pretty text-base text-clubhouse-ink">
                  {h.label}
                </span>
                <span className="shrink-0 text-lg font-bold tabular-nums text-clubhouse-ink">
                  {formatMeters(h.distanceMeters)}
                </span>
              </li>
            ))}
          </ul>
        </div>
      )}
    </div>
  )
}

function BigNumber({
  label,
  value,
  emphasized,
}: {
  label: string
  value: number
  emphasized?: boolean
}) {
  return (
    <div className="flex flex-col items-center">
      <span
        className={cn(
          "font-black leading-none tabular-nums",
          emphasized ? "text-6xl text-tee-strong" : "text-4xl text-clubhouse-ink",
        )}
      >
        {Math.round(value)}
      </span>
      <span
        className={cn(
          "mt-1 font-bold uppercase tracking-wide",
          emphasized ? "text-sm text-tee-strong" : "text-xs text-clubhouse-muted",
        )}
      >
        {label}
      </span>
    </div>
  )
}

function CompactNumber({
  label,
  value,
  emphasized,
}: {
  label: string
  value: number
  emphasized?: boolean
}) {
  return (
    <div className="flex flex-col items-center">
      <span
        className={cn(
          "font-black leading-none tabular-nums",
          emphasized ? "text-3xl text-tee-strong" : "text-xl text-clubhouse-ink",
        )}
      >
        {Math.round(value)}
      </span>
      <span className="text-[0.65rem] font-bold uppercase tracking-wide text-clubhouse-muted">
        {label}
      </span>
    </div>
  )
}

function buildDiagramAria(
  distances: Props["distances"],
  hazards: DiagramHazard[],
  player: Props["playerPosition"],
) {
  const base = `Baneskisse. Senter ${Math.round(distances.middle)} meter til green. Din posisjon markert.`
  if (hazards.length === 0) return `${base} Ingen hindringer.`
  const list = hazards
    .map((h) => `${h.label} ${Math.round(h.distanceMeters)} meter`)
    .join(", ")
  return `${base} Hindringer: ${list}.`
}
