"use client"

import type { ApiGender, Course } from "@/lib/ny-runde/types"
import { createOwnCourse } from "@/lib/ny-runde/api"
import { cn } from "@/lib/utils"
import { Plus, Trash2 } from "lucide-react"
import { useMemo, useState } from "react"
import { Field, NativeSelect, TextInput, Toggle, useAutoFocus } from "./primitives"

interface DraftRating {
  cr: string
  slope: string
  par: string
}
interface DraftTee {
  id: string
  name: string
  menEnabled: boolean
  womenEnabled: boolean
  men: DraftRating
  women: DraftRating
}
interface DraftHole {
  par: number
  si: number | 0 // 0 = ikke satt
}

let teeCounter = 0
function newTee(): DraftTee {
  teeCounter += 1
  return {
    id: `draft-tee-${teeCounter}`,
    name: "",
    menEnabled: true,
    womenEnabled: false,
    men: { cr: "", slope: "", par: "" },
    women: { cr: "", slope: "", par: "" },
  }
}

// seed.tees har KUN genders (ikke CR/Slope-tall) -- et forhåndsutfylt
// utslag fra en mal kan derfor bare forhåndsutfylle navn+hvilke(t) kjønn
// som er aktive, ikke selve ratingtallene (de er ikke kjent klient-side).
function seedToDraft(seed?: Course): { holes: DraftHole[]; tees: DraftTee[]; name: string } {
  if (!seed) {
    return {
      name: "",
      holes: Array.from({ length: 18 }, () => ({ par: 4, si: 0 })),
      tees: [newTee()],
    }
  }
  const holes: DraftHole[] = seed.templateHoles?.length
    ? seed.templateHoles.map((h) => ({ par: h.par, si: h.stroke_index }))
    : Array.from({ length: 18 }, () => ({ par: 4, si: 0 }))
  const tees: DraftTee[] = seed.templateTees?.length
    ? seed.templateTees.map((t) => {
        teeCounter += 1
        const men = t.ratings.find((r) => r.gender === "m")
        const women = t.ratings.find((r) => r.gender === "f")
        return {
          id: `draft-tee-${teeCounter}`,
          name: t.name,
          menEnabled: !!men,
          womenEnabled: !!women,
          men: men ? { cr: String(men.course_rating), slope: String(men.slope_rating), par: String(men.par) } : { cr: "", slope: "", par: "" },
          women: women ? { cr: String(women.course_rating), slope: String(women.slope_rating), par: String(women.par) } : { cr: "", slope: "", par: "" },
        }
      })
    : [newTee()]
  return { name: `${seed.name} (kopi)`, holes, tees }
}

function ratingComplete(r: DraftRating) {
  return r.cr.trim() !== "" && r.slope.trim() !== "" && r.par.trim() !== ""
}

export function CreateCourseForm({
  seed,
  onCancel,
  onCreate,
}: {
  seed?: Course
  onCancel: () => void
  onCreate: (course: Course) => void
}) {
  const initial = useMemo(() => seedToDraft(seed), [seed])
  const [name, setName] = useState(initial.name)
  const [holes, setHoles] = useState<DraftHole[]>(initial.holes)
  const [tees, setTees] = useState<DraftTee[]>(initial.tees)
  const [submitting, setSubmitting] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const nameRef = useAutoFocus<HTMLInputElement>(true)

  const siValues = holes.map((h) => h.si)
  const siError = useMemo(() => {
    const filled = siValues.filter((v) => v >= 1 && v <= 18)
    const set = new Set(filled)
    const complete = set.size === 18 && filled.length === 18
    return complete ? null : "Hver stroke-indeks (1–18) må brukes nøyaktig én gang."
  }, [siValues])

  const teesValid = tees.every((t) => {
    if (!t.name.trim()) return false
    if (!t.menEnabled && !t.womenEnabled) return false
    if (t.menEnabled && !ratingComplete(t.men)) return false
    if (t.womenEnabled && !ratingComplete(t.women)) return false
    return true
  })

  const canSubmit = name.trim() !== "" && !siError && tees.length >= 1 && teesValid && !submitting

  function setHole(i: number, patch: Partial<DraftHole>) {
    setHoles((prev) => prev.map((h, idx) => (idx === i ? { ...h, ...patch } : h)))
  }
  function setTee(id: string, patch: Partial<DraftTee>) {
    setTees((prev) => prev.map((t) => (t.id === id ? { ...t, ...patch } : t)))
  }
  function setTeeRating(id: string, gender: "men" | "women", patch: Partial<DraftRating>) {
    setTees((prev) => prev.map((t) => (t.id === id ? { ...t, [gender]: { ...t[gender], ...patch } } : t)))
  }

  async function submit() {
    if (!canSubmit) return
    setSubmitting(true)
    setError(null)
    try {
      const toRatings = (t: DraftTee) => {
        const ratings: { gender: ApiGender; course_rating: number; slope_rating: number; par: number }[] = []
        if (t.menEnabled) ratings.push({ gender: "m", course_rating: Number.parseFloat(t.men.cr), slope_rating: Number.parseInt(t.men.slope, 10), par: Number.parseInt(t.men.par, 10) })
        if (t.womenEnabled) ratings.push({ gender: "f", course_rating: Number.parseFloat(t.women.cr), slope_rating: Number.parseInt(t.women.slope, 10), par: Number.parseInt(t.women.par, 10) })
        return ratings
      }
      // Kun personlige baner (ikke offisielle teeoff-baner) kan "forkes" --
      // seed.id er et syntetisk teeoff-N-id for offisielle baner, en ekte
      // UUID for personlige (se courseFromOfficial/fetchOwnCourse i api.ts).
      const forkedFromId = seed && !seed.id.startsWith("teeoff-") ? seed.id : null
      const course = await createOwnCourse({
        name: name.trim(),
        holes: holes.map((h, i) => ({ hole_number: i + 1, par: h.par, stroke_index: h.si })),
        tees: tees.map((t) => ({ name: t.name.trim(), ratings: toRatings(t) })),
        forkedFromId,
      })
      onCreate(course)
    } catch {
      setError("Klarte ikke å opprette banen. Sjekk at hull og utslag er fylt ut riktig.")
      setSubmitting(false)
    }
  }

  return (
    <div className="flex flex-col gap-5">
      <Field label="Navn på banen" htmlFor="cc-name">
        <TextInput
          id="cc-name"
          ref={nameRef}
          value={name}
          onChange={(e) => setName(e.target.value)}
          placeholder="F.eks. Skogsbanen"
          maxLength={120}
        />
      </Field>

      {error ? (
        <p role="alert" className="text-xs text-[var(--nr-danger)]">
          {error}
        </p>
      ) : null}

      {/* Hull */}
      <div className="flex flex-col gap-2">
        <div className="flex items-center justify-between">
          <h3 className="text-sm font-semibold text-[var(--nr-ink)]">Hull</h3>
          <span className="text-xs text-[var(--nr-muted)]">Par og stroke-indeks for 18 hull</span>
        </div>
        <div className="overflow-hidden rounded-xl border border-[var(--nr-border)]">
          <div className="grid grid-cols-[auto_1fr_1fr] gap-px bg-[var(--nr-border)] text-xs">
            <div className="bg-[var(--nr-surface-2)] px-3 py-2 font-medium text-[var(--nr-muted)]">Hull</div>
            <div className="bg-[var(--nr-surface-2)] px-3 py-2 font-medium text-[var(--nr-muted)]">Par</div>
            <div className="bg-[var(--nr-surface-2)] px-3 py-2 font-medium text-[var(--nr-muted)]">Stroke-indeks</div>
            {holes.map((h, i) => (
              <HoleRow key={i} index={i} hole={h} onChange={(patch) => setHole(i, patch)} />
            ))}
          </div>
        </div>
        {siError ? (
          <p role="alert" className="text-xs text-[var(--nr-danger)]">
            {siError}
          </p>
        ) : (
          <p className="text-xs text-[var(--nr-ok)]">Alle stroke-indekser 1–18 er satt.</p>
        )}
      </div>

      {/* Utslag */}
      <div className="flex flex-col gap-3">
        <div className="flex items-center justify-between">
          <h3 className="text-sm font-semibold text-[var(--nr-ink)]">Utslag</h3>
          <button
            type="button"
            onClick={() => setTees((p) => [...p, newTee()])}
            className="inline-flex min-h-9 items-center gap-1.5 rounded-lg border border-[var(--nr-border)] bg-[var(--nr-surface)] px-3 text-[13px] font-medium text-[var(--nr-accent)] transition-colors hover:bg-[var(--nr-surface-2)] focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-[var(--nr-accent-ring)]/40"
          >
            <Plus className="h-4 w-4" aria-hidden="true" />
            Legg til utslag
          </button>
        </div>

        {tees.map((t, i) => (
          <div key={t.id} className="rounded-xl border border-[var(--nr-border)] bg-[var(--nr-surface-2)] p-3">
            <div className="flex items-end gap-2">
              <Field label="Navn på utslag" htmlFor={`${t.id}-name`} className="flex-1">
                <TextInput
                  id={`${t.id}-name`}
                  value={t.name}
                  onChange={(e) => setTee(t.id, { name: e.target.value })}
                  placeholder={`Utslag ${i + 1}`}
                  invalid={t.name.trim() === ""}
                  className="bg-[var(--nr-surface)]"
                />
              </Field>
              <button
                type="button"
                onClick={() => tees.length > 1 && setTees((p) => p.filter((x) => x.id !== t.id))}
                disabled={tees.length <= 1}
                aria-label={`Fjern ${t.name.trim() || `utslag ${i + 1}`}`}
                className="mb-0.5 flex h-11 w-11 items-center justify-center rounded-lg border border-[var(--nr-border)] bg-[var(--nr-surface)] text-[var(--nr-muted)] transition-colors hover:text-[var(--nr-danger)] disabled:cursor-not-allowed disabled:opacity-40"
              >
                <Trash2 className="h-4 w-4" aria-hidden="true" />
              </button>
            </div>

            <div className="mt-3 flex flex-col gap-3">
              <RatingBlock
                title="Herre-rating"
                enabled={t.menEnabled}
                onToggle={(v) => setTee(t.id, { menEnabled: v })}
                rating={t.men}
                onChange={(patch) => setTeeRating(t.id, "men", patch)}
                idPrefix={`${t.id}-men`}
              />
              <RatingBlock
                title="Dame-rating"
                enabled={t.womenEnabled}
                onToggle={(v) => setTee(t.id, { womenEnabled: v })}
                rating={t.women}
                onChange={(patch) => setTeeRating(t.id, "women", patch)}
                idPrefix={`${t.id}-women`}
              />
              {!t.menEnabled && !t.womenEnabled ? (
                <p role="alert" className="text-xs text-[var(--nr-danger)]">
                  Minst én rating (herre eller dame) må være aktiv for dette utslaget.
                </p>
              ) : null}
            </div>
          </div>
        ))}
      </div>

      <div className="flex items-center justify-between gap-3 pt-1">
        <button
          type="button"
          onClick={onCancel}
          className="inline-flex min-h-11 items-center rounded-lg border border-[var(--nr-border)] bg-[var(--nr-surface)] px-4 text-sm font-medium text-[var(--nr-ink)] transition-colors hover:bg-[var(--nr-surface-2)]"
        >
          Avbryt
        </button>
        <button
          type="button"
          onClick={() => void submit()}
          disabled={!canSubmit}
          className="inline-flex min-h-11 items-center rounded-lg bg-[var(--nr-accent)] px-5 text-sm font-semibold text-[var(--nr-accent-ink)] transition-colors hover:brightness-110 disabled:cursor-not-allowed disabled:opacity-40"
        >
          {submitting ? "Lagrer…" : "Lagre bane"}
        </button>
      </div>
    </div>
  )
}

function HoleRow({
  index,
  hole,
  onChange,
}: {
  index: number
  hole: DraftHole
  onChange: (patch: Partial<DraftHole>) => void
}) {
  return (
    <>
      <div className="flex items-center bg-[var(--nr-surface)] px-3 py-1.5 text-sm font-medium tabular-nums text-[var(--nr-muted)]">
        {index + 1}
      </div>
      <div className="bg-[var(--nr-surface)] px-2 py-1.5">
        <NativeSelect
          aria-label={`Par for hull ${index + 1}`}
          value={hole.par}
          onChange={(e) => onChange({ par: Number.parseInt(e.target.value, 10) })}
          className="h-9 bg-[var(--nr-surface-2)]"
        >
          {[3, 4, 5, 6].map((p) => (
            <option key={p} value={p}>
              {p}
            </option>
          ))}
        </NativeSelect>
      </div>
      <div className="bg-[var(--nr-surface)] px-2 py-1.5">
        <NativeSelect
          aria-label={`Stroke-indeks for hull ${index + 1}`}
          value={hole.si || ""}
          onChange={(e) => onChange({ si: Number.parseInt(e.target.value, 10) })}
          className="h-9 bg-[var(--nr-surface-2)]"
        >
          <option value="">–</option>
          {Array.from({ length: 18 }, (_, i) => i + 1).map((si) => (
            <option key={si} value={si}>
              {si}
            </option>
          ))}
        </NativeSelect>
      </div>
    </>
  )
}

function RatingBlock({
  title,
  enabled,
  onToggle,
  rating,
  onChange,
  idPrefix,
}: {
  title: string
  enabled: boolean
  onToggle: (v: boolean) => void
  rating: DraftRating
  onChange: (patch: Partial<DraftRating>) => void
  idPrefix: string
}) {
  return (
    <div className={cn("rounded-lg border p-3", enabled ? "border-[var(--nr-accent-ring)] bg-[var(--nr-surface)]" : "border-[var(--nr-border)] bg-[var(--nr-surface)]")}>
      <Toggle checked={enabled} onChange={onToggle} label={title} />
      {enabled ? (
        <div className="mt-3 grid grid-cols-3 gap-2">
          <Field label="Course Rating" htmlFor={`${idPrefix}-cr`}>
            <TextInput
              id={`${idPrefix}-cr`}
              inputMode="decimal"
              value={rating.cr}
              onChange={(e) => onChange({ cr: e.target.value })}
              placeholder="72.1"
              invalid={rating.cr.trim() === ""}
              className="bg-[var(--nr-surface-2)]"
            />
          </Field>
          <Field label="Slope" htmlFor={`${idPrefix}-slope`}>
            <TextInput
              id={`${idPrefix}-slope`}
              inputMode="numeric"
              value={rating.slope}
              onChange={(e) => onChange({ slope: e.target.value.replace(/[^\d]/g, "") })}
              placeholder="128"
              invalid={rating.slope.trim() === ""}
              className="bg-[var(--nr-surface-2)]"
            />
          </Field>
          <Field label="Par" htmlFor={`${idPrefix}-par`}>
            <TextInput
              id={`${idPrefix}-par`}
              inputMode="numeric"
              value={rating.par}
              onChange={(e) => onChange({ par: e.target.value.replace(/[^\d]/g, "") })}
              placeholder="72"
              invalid={rating.par.trim() === ""}
              className="bg-[var(--nr-surface-2)]"
            />
          </Field>
        </div>
      ) : null}
    </div>
  )
}
