"use client"

// Massimport av spillere via CSV (2026-08-17) -- MIDLERTIDIG hånd-kodet
// versjon, bygget for å verifisere hele kjeden (CSV -> kolonnetilknytning
// -> redigerbar tabell -> POST .../players/bulk -> løkke over
// participants/roster-endepunktene) ende-til-ende FØR V0-eksporten er
// klar. Erstattes med V0-designet visning når den kommer tilbake (samme
// rekkefølge som FlagPlantSheet, se ARCHITECTURE_DECISIONS.md).

import { useRef, useState } from "react"
import Papa from "papaparse"
import { Upload, X } from "lucide-react"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"

type FieldKey =
  | "display_name"
  | "email"
  | "handicap_index"
  | "gender"
  | "birth_date"
  | "mobile"
  | "club"
  | "nickname"
  | "country"
  | "club_member_number"
  | "first_name"
  | "last_name"
  | "comment"
  | "team_name"
  | "class_name"

type DraftRow = {
  key: string
} & Record<FieldKey, string>

const EMPTY_ROW: Omit<DraftRow, "key"> = {
  display_name: "",
  email: "",
  handicap_index: "",
  gender: "",
  birth_date: "",
  mobile: "",
  club: "",
  nickname: "",
  country: "",
  club_member_number: "",
  first_name: "",
  last_name: "",
  comment: "",
  team_name: "",
  class_name: "",
}

const FIELD_LABELS: Record<FieldKey, string> = {
  display_name: "Navn",
  email: "E-post",
  handicap_index: "HCP",
  gender: "Kjønn",
  birth_date: "Fødselsdato",
  mobile: "Mobil",
  club: "Klubb",
  nickname: "Kallenavn",
  country: "Land",
  club_member_number: "Medlemsnr.",
  first_name: "Fornavn",
  last_name: "Etternavn",
  comment: "Kommentar",
  team_name: "Lag",
  class_name: "Klasse",
}

// Fuzzy gjetting av kolonnetilknytning -- små bokstaver, uten mellomrom/
// bindestrek, sammenlignet mot vanlige norske/engelske varianter.
const HEADER_GUESSES: Record<string, FieldKey> = {
  navn: "display_name",
  name: "display_name",
  fulltnavn: "display_name",
  spillernavn: "display_name",
  epost: "email",
  email: "email",
  mail: "email",
  hcp: "handicap_index",
  handicap: "handicap_index",
  spillehandicap: "handicap_index",
  kjonn: "gender",
  gender: "gender",
  fodselsdato: "birth_date",
  fodtdato: "birth_date",
  birthdate: "birth_date",
  fodt: "birth_date",
  mobil: "mobile",
  mobile: "mobile",
  telefon: "mobile",
  phone: "mobile",
  klubb: "club",
  club: "club",
  medlemsnr: "club_member_number",
  medlemsnummer: "club_member_number",
  fornavn: "first_name",
  firstname: "first_name",
  etternavn: "last_name",
  lastname: "last_name",
  lag: "team_name",
  team: "team_name",
  klasse: "class_name",
  class: "class_name",
  kommentar: "comment",
  comment: "comment",
  land: "country",
  country: "country",
  kallenavn: "nickname",
  nickname: "nickname",
}

function normalizeHeader(h: string): string {
  return h.trim().toLowerCase().replace(/[\s_-]+/g, "")
}

function guessField(header: string): FieldKey | "" {
  return HEADER_GUESSES[normalizeHeader(header)] ?? ""
}

type ApiPlayer = {
  id: string
  display_name: string
  handicap_index: number | null
  gender: string | null
  mobile: string | null
  email: string | null
  birth_date: string | null
  nickname: string | null
  country: string | null
  club: string | null
  club_member_number: string | null
  first_name: string | null
  last_name: string | null
  paid: boolean
  comment: string | null
}

type Mode =
  | { kind: "team"; teams: { id: string; name: string }[] }
  | { kind: "individual"; classes: { id: string; name: string }[] }

export function PlayerImportPanel({
  organizationId,
  tournamentId,
  mode,
  onClose,
  onImportComplete,
}: {
  organizationId: string
  tournamentId: string
  mode: Mode
  onClose: () => void
  onImportComplete: (createdOrUpdated: { player: ApiPlayer; status: string }[]) => void
}) {
  const [step, setStep] = useState<"upload" | "map" | "edit" | "saving" | "done">("upload")
  const [csvHeaders, setCsvHeaders] = useState<string[]>([])
  const [csvRows, setCsvRows] = useState<string[][]>([])
  const [mapping, setMapping] = useState<Record<number, FieldKey | "">>({})
  const [rows, setRows] = useState<DraftRow[]>([])
  const [error, setError] = useState<string | null>(null)
  const [saveErrors, setSaveErrors] = useState<string[]>([])
  const fileInputRef = useRef<HTMLInputElement>(null)

  function handleFile(file: File) {
    setError(null)
    Papa.parse<string[]>(file, {
      skipEmptyLines: true,
      complete: (result) => {
        const data = result.data
        if (data.length === 0) {
          setError("Fant ingen rader i filen.")
          return
        }
        const headers = data[0]
        const body = data.slice(1)
        setCsvHeaders(headers)
        setCsvRows(body)
        const guessed: Record<number, FieldKey | ""> = {}
        headers.forEach((h, i) => {
          guessed[i] = guessField(h)
        })
        setMapping(guessed)
        setStep("map")
      },
      error: () => setError("Klarte ikke å lese filen. Er det en gyldig CSV?"),
    })
  }

  function confirmMapping() {
    const mapped: DraftRow[] = csvRows.map((cells, i) => {
      const row: DraftRow = { key: `csv-${i}`, ...EMPTY_ROW }
      csvHeaders.forEach((_, colIdx) => {
        const field = mapping[colIdx]
        if (field) row[field] = (cells[colIdx] ?? "").trim()
      })
      return row
    })
    setRows(mapped)
    setStep("edit")
  }

  function updateCell(key: string, field: FieldKey, value: string) {
    setRows((prev) => prev.map((r) => (r.key === key ? { ...r, [field]: value } : r)))
  }

  function addBlankRow() {
    setRows((prev) => [...prev, { key: `manual-${Date.now()}`, ...EMPTY_ROW }])
  }

  function removeRow(key: string) {
    setRows((prev) => prev.filter((r) => r.key !== key))
  }

  function teamIdForName(name: string): string | null {
    if (mode.kind !== "team") return null
    const match = mode.teams.find((t) => t.name.trim().toLowerCase() === name.trim().toLowerCase())
    return match?.id ?? null
  }

  function classIdForName(name: string): string | null {
    if (mode.kind !== "individual") return null
    const match = mode.classes.find((c) => c.name.trim().toLowerCase() === name.trim().toLowerCase())
    return match?.id ?? null
  }

  async function handleSave() {
    const validRows = rows.filter((r) => r.display_name.trim().length > 0)
    if (validRows.length === 0) {
      setError("Ingen rader med navn å lagre.")
      return
    }
    setStep("saving")
    setError(null)
    setSaveErrors([])
    try {
      const payload = validRows.map((r) => ({
        display_name: r.display_name.trim(),
        email: r.email.trim() || null,
        handicap_index: r.handicap_index.trim() ? Number(r.handicap_index) : null,
        gender: r.gender.trim() || null,
        birth_date: r.birth_date.trim() || null,
        mobile: r.mobile.trim() || null,
        club: r.club.trim() || null,
        nickname: r.nickname.trim() || null,
        country: r.country.trim() || null,
        club_member_number: r.club_member_number.trim() || null,
        first_name: r.first_name.trim() || null,
        last_name: r.last_name.trim() || null,
        comment: r.comment.trim() || null,
      }))
      const bulkRes = await fetch(`/orgs/${organizationId}/players/bulk`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        credentials: "include",
        body: JSON.stringify(payload),
      })
      if (!bulkRes.ok) throw new Error(`bulk: ${bulkRes.status}`)
      const results: { player: ApiPlayer; status: string }[] = await bulkRes.json()

      const errors: string[] = []
      for (let i = 0; i < validRows.length; i++) {
        const row = validRows[i]
        const player = results[i]?.player
        if (!player) continue
        if (mode.kind === "team") {
          const teamId = teamIdForName(row.team_name)
          if (!teamId) {
            if (row.team_name.trim()) {
              errors.push(`${row.display_name}: fant ikke laget "${row.team_name}" -- lagt i spillerpoolen, ikke på lag.`)
            }
            continue
          }
          const res = await fetch(`/orgs/${organizationId}/teams/${teamId}/roster`, {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            credentials: "include",
            body: JSON.stringify({ player_id: player.id }),
          })
          if (!res.ok && res.status !== 409) {
            errors.push(`${row.display_name}: klarte ikke å legge til på laget.`)
          }
        } else {
          const classId = row.class_name.trim() ? classIdForName(row.class_name) : null
          const res = await fetch(`/orgs/${organizationId}/tournaments/${tournamentId}/participants`, {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            credentials: "include",
            body: JSON.stringify({ player_id: player.id, class_id: classId }),
          })
          if (!res.ok && res.status !== 409) {
            errors.push(`${row.display_name}: klarte ikke å melde på turneringen.`)
          }
        }
      }
      setSaveErrors(errors)
      setStep("done")
      onImportComplete(results)
    } catch {
      setError("Importen feilet. Prøv igjen.")
      setStep("edit")
    }
  }

  return (
    <div className="fixed inset-0 z-50 flex flex-col bg-background">
      <header className="flex min-h-14 shrink-0 items-center justify-between border-b border-border px-4">
        <h2 className="text-base font-extrabold text-foreground">Importer spillere fra CSV</h2>
        <button
          type="button"
          onClick={onClose}
          aria-label="Lukk"
          className="flex size-11 items-center justify-center rounded-xl text-foreground hover:bg-accent"
        >
          <X aria-hidden="true" className="size-5" />
        </button>
      </header>

      <main className="flex-1 overflow-y-auto p-5">
        {error && (
          <div className="mb-4 rounded-2xl border border-destructive/30 bg-destructive/5 px-4 py-3 text-sm font-medium text-destructive">
            {error}
          </div>
        )}

        {step === "upload" && (
          <div className="flex flex-col items-center gap-4 rounded-2xl border-2 border-dashed border-border p-10 text-center">
            <Upload aria-hidden="true" className="size-8 text-muted-foreground" />
            <p className="text-sm text-muted-foreground">Velg en CSV-fil med spillere.</p>
            <input
              ref={fileInputRef}
              type="file"
              accept=".csv,text/csv"
              className="hidden"
              onChange={(e) => {
                const file = e.target.files?.[0]
                if (file) handleFile(file)
              }}
            />
            <Button type="button" onClick={() => fileInputRef.current?.click()} className="min-h-11">
              Velg fil
            </Button>
          </div>
        )}

        {step === "map" && (
          <div className="flex flex-col gap-4">
            <p className="text-sm text-muted-foreground">
              Velg hvilket felt hver kolonne skal fylle. "Ignorer" hopper over kolonnen.
            </p>
            <div className="flex flex-col gap-3">
              {csvHeaders.map((h, i) => (
                <div key={i} className="flex items-center gap-3 rounded-xl border border-border p-3">
                  <span className="min-w-0 flex-1 truncate text-sm font-semibold text-foreground">{h}</span>
                  <select
                    value={mapping[i] ?? ""}
                    onChange={(e) =>
                      setMapping((prev) => ({ ...prev, [i]: e.target.value as FieldKey | "" }))
                    }
                    className="min-h-11 rounded-lg border border-input bg-transparent px-2 text-sm"
                  >
                    <option value="">Ignorer</option>
                    {(Object.keys(FIELD_LABELS) as FieldKey[])
                      .filter((f) => mode.kind === "team" || f !== "team_name")
                      .filter((f) => mode.kind === "individual" || f !== "class_name")
                      .map((f) => (
                        <option key={f} value={f}>
                          {FIELD_LABELS[f]}
                        </option>
                      ))}
                  </select>
                </div>
              ))}
            </div>
            <Button type="button" onClick={confirmMapping} className="min-h-11 self-start">
              Neste: forhåndsvis {csvRows.length} rader
            </Button>
          </div>
        )}

        {(step === "edit" || step === "saving") && (
          <div className="flex flex-col gap-4">
            <div className="overflow-x-auto rounded-2xl border border-border">
              <table className="w-full min-w-[900px] border-collapse text-sm">
                <thead>
                  <tr className="border-b border-border bg-muted/50">
                    {(Object.keys(FIELD_LABELS) as FieldKey[])
                      .filter((f) => mode.kind === "team" || f !== "team_name")
                      .filter((f) => mode.kind === "individual" || f !== "class_name")
                      .map((f) => (
                        <th key={f} className="whitespace-nowrap px-2 py-2 text-left font-bold text-foreground">
                          {FIELD_LABELS[f]}
                        </th>
                      ))}
                    <th className="px-2 py-2" />
                  </tr>
                </thead>
                <tbody>
                  {rows.map((row) => (
                    <tr key={row.key} className="border-b border-border last:border-0">
                      {(Object.keys(FIELD_LABELS) as FieldKey[])
                        .filter((f) => mode.kind === "team" || f !== "team_name")
                        .filter((f) => mode.kind === "individual" || f !== "class_name")
                        .map((f) => (
                          <td key={f} className="px-2 py-1.5">
                            <Input
                              value={row[f]}
                              onChange={(e) => updateCell(row.key, f, e.target.value)}
                              disabled={step === "saving"}
                              className="min-w-24"
                            />
                          </td>
                        ))}
                      <td className="px-2 py-1.5">
                        <button
                          type="button"
                          onClick={() => removeRow(row.key)}
                          disabled={step === "saving"}
                          aria-label={`Slett rad for ${row.display_name || "tom rad"}`}
                          className="flex size-9 items-center justify-center rounded-lg text-muted-foreground hover:bg-accent hover:text-destructive"
                        >
                          <X aria-hidden="true" className="size-4" />
                        </button>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
            <div className="flex flex-wrap items-center gap-3">
              <Button type="button" variant="outline" onClick={addBlankRow} disabled={step === "saving"} className="min-h-11">
                Legg til rad
              </Button>
              <Button type="button" onClick={handleSave} disabled={step === "saving"} className="min-h-11">
                {step === "saving" ? "Lagrer …" : `Lagre ${rows.filter((r) => r.display_name.trim()).length} spillere`}
              </Button>
            </div>
          </div>
        )}

        {step === "done" && (
          <div className="flex flex-col gap-4">
            <p className="text-sm font-semibold text-foreground">Importen er fullført.</p>
            {saveErrors.length > 0 && (
              <div className="rounded-2xl border border-destructive/30 bg-destructive/5 p-4 text-sm text-destructive">
                <p className="mb-2 font-bold">Noen rader trenger oppfølging:</p>
                <ul className="list-disc pl-5">
                  {saveErrors.map((e, i) => (
                    <li key={i}>{e}</li>
                  ))}
                </ul>
              </div>
            )}
            <Button type="button" onClick={onClose} className="min-h-11 self-start">
              Lukk
            </Button>
          </div>
        )}
      </main>
    </div>
  )
}
