/**
 * "Datensatz sichern"/"Datensatz laden" — Einstellungen/Fahrzeugprofil.
 * Vorlage: `vDatensatzPopup()` im Panel (audi-dashboard-app.js).
 *
 * "Sichern" löst vier sofortige, rein clientseitige Exporte aus
 * (Fahrzeugprofil als JSON, Fahrten/Tankvorgänge/Wartungsplan als CSV).
 * "Laden" spiegelt dieselben vier Dateien als Dateiauswahl - Fahrzeugprofil
 * über den bestehenden profil_schreiben-Dienst (api.profilSchreiben()),
 * die drei CSV-Datensätze über den neuen csv_importieren-Dienst
 * (api.csvImportieren(), custom_components/audi_dashboard/csv_import.py):
 * eine Zeile mit bekannter ID aktualisiert nur ihre eigenen Spalten, alles
 * andere am Datensatz bleibt unangetastet - siehe dessen Moduldocstring für
 * die Begründung.
 *
 * Die CSV-Spaltennamen sind absichtlich BYTE-IDENTISCH zum Panel-Export
 * ("ID","Start","Ende","km","Art","Status" usw.) - derselbe Backend-Parser
 * bedient beide Oberflächen, eine hier exportierte Datei muss sich also auch
 * im Panel importieren lassen und umgekehrt. Vorher hatte diese Seite eigene,
 * abweichende Spaltennamen ("Beginn"/"Strecke km"/"Dauer s") - die gab es
 * nur zum Lesen in einer Tabelle, nie zum Reimport, ein Rundlauf wäre also
 * gescheitert.
 */

import { useEffect, useRef, useState } from "react"

import { ActionButton, Popup } from "@audi-dash/ui"

import type { CsvImportErgebnis, DataMetricApi, Fahrt, Profil, Tankvorgang } from "../api"
import { de, eur } from "../format"
import { csvHerunterladen } from "./csv"
import type { ServicebuchEintrag } from "./Service"

type Art = "fahrzeugprofil" | "fahrten" | "tanken" | "service"

const ARTEN: [Art, string][] = [
  ["fahrzeugprofil", "Fahrzeugprofil"],
  ["fahrten", "Fahrten"],
  ["tanken", "Tankvorgänge"],
  ["service", "Wartungsplan"],
]

function exportieren(
  art: Art,
  rohprofil: Profil | null,
  fahrten: readonly Fahrt[],
  tankvorgaenge: readonly Tankvorgang[],
  wartungsplan: readonly ServicebuchEintrag[],
) {
  if (art === "fahrzeugprofil") {
    const blob = new Blob([JSON.stringify(rohprofil, null, 2)], { type: "application/json" })
    const url = URL.createObjectURL(blob)
    const verweis = document.createElement("a")
    verweis.href = url
    verweis.download = "fahrzeugprofil.json"
    verweis.click()
    URL.revokeObjectURL(url)
    return
  }
  if (art === "fahrten") {
    csvHerunterladen(
      "fahrten",
      ["ID", "Start", "Ende", "km", "Art", "Status"],
      fahrten.map((f) => [f.trip_id, f.ts_start, f.ts_end, f.distance_km ?? "", f.art, f.status]),
    )
    return
  }
  if (art === "tanken") {
    csvHerunterladen(
      "tankvorgaenge",
      ["ID", "Zeitpunkt", "Station", "Liter", "€/l", "Kosten €"],
      tankvorgaenge.map((t) => [
        t.tank_id,
        t.ts,
        t.station_name ?? "",
        t.liters ?? "",
        t.liters && t.fuel_total_eur != null ? de(t.fuel_total_eur / t.liters, 2) : "",
        t.fuel_total_eur != null ? eur(t.fuel_total_eur) : "",
      ]),
    )
    return
  }
  csvHerunterladen(
    "wartungsplan",
    ["Datum", "km", "Art", "Werkstatt", "Kosten €"],
    wartungsplan.map((e) => [
      e.datum ?? "",
      e.km != null ? de(e.km) : "",
      e.art ?? "",
      e.werkstatt ?? "",
      e.kosten != null ? eur(e.kosten) : "",
    ]),
  )
}

function ergebnisText(art: Art, e: CsvImportErgebnis): string {
  if (art === "fahrzeugprofil") return "Fahrzeugprofil geladen."
  const teile: string[] = []
  if (e.angelegt) teile.push(`${de(e.angelegt)} neu angelegt`)
  if (e.aktualisiert) teile.push(`${de(e.aktualisiert)} aktualisiert`)
  if (e.uebersprungen) teile.push(`${de(e.uebersprungen)} übersprungen`)
  return teile.length ? teile.join(" · ") : "Keine gültigen Zeilen in der Datei gefunden."
}

export function DatensatzPopup({
  offen,
  modus,
  beiSchliessen,
  api,
  rohprofil,
  fahrten,
  tankvorgaenge,
  wartungsplan,
  beiProfilGeladen,
  beiFertig,
}: {
  offen: boolean
  modus: "sichern" | "laden"
  beiSchliessen: () => void
  api: DataMetricApi
  rohprofil: Profil | null
  fahrten: readonly Fahrt[]
  tankvorgaenge: readonly Tankvorgang[]
  wartungsplan: readonly ServicebuchEintrag[]
  /** Nach einem geladenen Fahrzeugprofil: den neuen Stand übernehmen. */
  beiProfilGeladen: (profil: Profil) => Promise<void>
  /** Nach einem erfolgreichen CSV-Import: Fahrten-/Tankvorgangslisten neu laden. */
  beiFertig: () => void
}) {
  const [laeuft, setzeLaeuft] = useState<Art | null>(null)
  const [ergebnis, setzeErgebnis] = useState<{ art: Art; text: string } | null>(null)
  const [fehler, setzeFehler] = useState<string | null>(null)
  const eingaben = useRef<Partial<Record<Art, HTMLInputElement | null>>>({})
  const aktiv = useRef(true)
  useEffect(() => {
    aktiv.current = true
    return () => {
      aktiv.current = false
    }
  }, [])

  useEffect(() => {
    if (offen) {
      setzeErgebnis(null)
      setzeFehler(null)
      setzeLaeuft(null)
    }
  }, [offen])

  const schliessen = () => {
    if (laeuft) return
    beiSchliessen()
  }

  const dateiGewaehlt = async (art: Art, datei: File) => {
    setzeLaeuft(art)
    setzeErgebnis(null)
    setzeFehler(null)
    let inhalt: string
    try {
      inhalt = await datei.text()
    } catch {
      if (!aktiv.current) return
      setzeLaeuft(null)
      setzeFehler("Die Datei ließ sich nicht lesen.")
      return
    }
    try {
      if (art === "fahrzeugprofil") {
        const profil = JSON.parse(inhalt) as Profil
        await beiProfilGeladen(profil)
        if (!aktiv.current) return
        setzeErgebnis({ art, text: ergebnisText(art, {}) })
      } else {
        const e = await api.csvImportieren(art, inhalt)
        if (!aktiv.current) return
        setzeErgebnis({ art, text: ergebnisText(art, e) })
        beiFertig()
      }
    } catch (err) {
      if (!aktiv.current) return
      setzeFehler(
        art === "fahrzeugprofil"
          ? `Die Datei ließ sich nicht lesen: ${err instanceof Error ? err.message : "unbekannter Fehler"}`
          : `Der Import ist fehlgeschlagen: ${err instanceof Error ? err.message : "unbekannter Fehler"}`,
      )
    } finally {
      if (aktiv.current) setzeLaeuft(null)
    }
  }

  return (
    <Popup open={offen} onClose={schliessen} variant="form" anchor="center">
      <span className="ads-eyebrow">{modus === "sichern" ? "Datensatz sichern" : "Datensatz laden"}</span>
      <p className="dm-fussnote">
        {modus === "sichern"
          ? "Semikolon als Trennzeichen und deutsches Zahlenformat, damit die Dateien ohne Umweg in Tabellenprogrammen aufgehen."
          : "Eine zuvor gesicherte, ggf. bearbeitete Datei wieder einspielen — eine Zeile mit bekannter ID aktualisiert nur ihre eigenen Spalten, alles andere bleibt unangetastet."}
      </p>
      {ARTEN.map(([art, label]) =>
        modus === "sichern" ? (
          <div key={art} style={{ marginTop: 12 }}>
            <ActionButton
              onClick={() => exportieren(art, rohprofil, fahrten, tankvorgaenge, wartungsplan)}
            >
              {label}
              {art === "fahrzeugprofil" ? " sichern" : " als CSV"}
            </ActionButton>
          </div>
        ) : (
          <div key={art} style={{ marginTop: 12 }}>
            <ActionButton
              onClick={() => eingaben.current[art]?.click()}
              disabled={laeuft !== null}
            >
              {laeuft === art ? "Lädt …" : `${label}${art === "fahrzeugprofil" ? " laden" : " (CSV) laden"}`}
            </ActionButton>
            <input
              ref={(el) => {
                eingaben.current[art] = el
              }}
              type="file"
              accept={art === "fahrzeugprofil" ? "application/json" : "text/csv"}
              hidden
              onChange={(e) => {
                const datei = e.target.files?.[0]
                e.target.value = ""
                if (datei) void dateiGewaehlt(art, datei)
              }}
            />
          </div>
        ),
      )}
      {ergebnis && <p className="dm-importergebnis">{ergebnis.text}</p>}
      {fehler && <p className="dm-fussnote dm-fussnote--warnung">{fehler}</p>}
      <div style={{ marginTop: 16 }}>
        <ActionButton onClick={beiSchliessen} disabled={laeuft !== null}>
          Fertig
        </ActionButton>
      </div>
    </Popup>
  )
}

