/**
 * Reifensätze. Vorlage: `vReifen()` im alten Panel.
 *
 * Der Kilometerstand je Satz kommt vom Backend (`reifenzaehler.py`) und wird
 * hier nie zurückgeschrieben — sonst überschriebe ein im Browser gehaltener
 * älterer Stand eine zwischenzeitliche Fortschreibung. Der Wechsel läuft
 * deshalb auch über einen eigenen Dienst statt über das Profil.
 */

import { useState } from "react"

import { Accordion, ActionButton, Feld, IconButton, Seg, Tile } from "@audi-dash/ui"

import { DIENST_DOMAIN } from "../api"
import { useDaten } from "../daten/DatenKontext"
import type { Reifensatz, ReifenArchivEintrag } from "../daten/profilAdapter"
import { datum, de, deOderStrich } from "../format"
import { SymbolPaket } from "../symbole"
import { Wertzeile, Werteliste, bestaetigen } from "./bausteine"
import { Bild } from "./Bild"
import { kalenderDateiLaden } from "./kalender"

export function Reifen() {
  const { fahrzeug, api, profilSpeichern } = useDaten()
  const [laeuft, setzeLaeuft] = useState(false)
  const [gezeigt, setzeGezeigt] = useState<"Sommer" | "Winter" | null>(null)

  if (!fahrzeug) return null

  const aktiv = fahrzeug.reifen.aktiv
  const anzeige = gezeigt ?? aktiv
  const satz: Reifensatz = anzeige === "Winter" ? fahrzeug.reifen.winter : fahrzeug.reifen.sommer
  const wechsel = fahrzeug.reifen.wechsel as { datum?: string; vereinbart?: boolean }

  const wechseln = async () => {
    const ziel = aktiv === "Sommer" ? "winter" : "sommer"
    if (!bestaetigen(`Auf ${ziel === "winter" ? "Winter" : "Sommer"}reifen umstellen?`)) return
    setzeLaeuft(true)
    try {
      // Eigener Dienst: das Backend rechnet zuerst den alten Satz ab und
      // schaltet erst dann um, damit keine Kilometer auf den neuen Satz
      // rutschen, die noch auf dem alten gefahren wurden.
      await api.rest.dienstAufrufen(DIENST_DOMAIN, "reifen_wechseln", { satz: ziel })
    } finally {
      setzeLaeuft(false)
    }
  }

  const archivieren = async () => {
    if (!bestaetigen("Neue Räder anlegen?")) return
    setzeLaeuft(true)
    try {
      // Eigener Dienst wie reifen_wechseln: archiviert den bisherigen Stand
      // und setzt den laufenden Satz zurück (km 0, Marke/Modell/DOT/Kommentar
      // leer - siehe reifen.py archivieren()).
      await api.reifenArchivieren(anzeige === "Winter" ? "winter" : "sommer")
    } finally {
      setzeLaeuft(false)
    }
  }

  const wechseldatumSetzen = async (neuesDatum: string) => {
    await profilSpeichern({
      fahrzeug: {
        ...fahrzeug,
        reifen: { ...fahrzeug.reifen, wechsel: { ...wechsel, datum: neuesDatum } },
      },
    })
  }

  return (
    <>
      <Tile>
        <span className="ads-eyebrow">Montiert</span>
        <div className="dm-detail__kopf">
          <div className="dm-detail__zahl">{aktiv}</div>
          <ActionButton onClick={() => void wechseln()} disabled={laeuft}>
            {laeuft ? "Stelle um …" : `Auf ${aktiv === "Sommer" ? "Winter" : "Sommer"} wechseln`}
          </ActionButton>
        </div>
        <Werteliste
          kinder={
            <>
              <Wertzeile
                label="Anzugsmoment der Radschrauben"
                wert={
                  fahrzeug.reifen.anzugsmoment != null
                    ? `${de(fahrzeug.reifen.anzugsmoment)} Nm`
                    : "—"
                }
              />
              <Wertzeile
                label="Nächster Wechseltermin"
                wert={wechsel.datum ? datum(wechsel.datum) : "—"}
              />
            </>
          }
        />
        <Feld label="Wechseltermin" last>
          <input
            className="dm-eingabe"
            type="date"
            value={wechsel.datum ?? ""}
            onChange={(e) => void wechseldatumSetzen(e.target.value)}
          />
        </Feld>
        {wechsel.datum && (
          <div style={{ marginTop: 14 }}>
            <ActionButton
              onClick={() =>
                kalenderDateiLaden(
                  "Reifenwechsel",
                  wechsel.datum!,
                  `Wechsel auf ${aktiv === "Sommer" ? "Winter" : "Sommer"}reifen`,
                )
              }
            >
              In den Kalender eintragen
            </ActionButton>
          </div>
        )}
      </Tile>

      <Seg
        options={[
          { value: "Sommer", label: "Sommer" },
          { value: "Winter", label: "Winter" },
        ]}
        value={anzeige}
        onChange={(wert) => setzeGezeigt(wert as "Sommer" | "Winter")}
      />

      <Tile>
        <span className="ads-eyebrow">
          {anzeige}reifen {anzeige === aktiv ? "· montiert" : "· eingelagert"}
        </span>
        <Bild
          datei={anzeige === "Winter" ? "rad-winter.webp" : "rad-sommer.webp"}
          beschreibung={`${anzeige}rad`}
          name={`${anzeige}rad`}
        />
        <div style={{ display: "flex", justifyContent: "flex-end", marginTop: -6 }}>
          <IconButton aria-label="Neue Räder anlegen" onClick={() => void archivieren()} disabled={laeuft}>
            <SymbolPaket groesse={18} />
          </IconButton>
        </div>
        <Werteliste
          kinder={
            <>
              <Wertzeile label="Gefahrene Strecke" wert={`${deOderStrich(satz["km"] as number)} km`} />
              <Wertzeile label="Größe" wert={(satz["mass"] as string) || "—"} />
              <Wertzeile
                label="Marke und Modell"
                wert={
                  [satz["marke"], satz["modell"]].filter(Boolean).join(" ") || "—"
                }
              />
              <Wertzeile label="DOT" wert={(satz["dot"] as string) || "—"} />
              <Wertzeile
                label="Luftdruck"
                wert={`${(satz["druck_vorne"] as string) || "—"} / ${(satz["druck_hinten"] as string) || "—"} bar`}
                zusatz="vorne / hinten"
              />
              {Boolean(satz["kommentar"]) && (
                <Wertzeile label="Notiz" wert={satz["kommentar"] as string} />
              )}
            </>
          }
        />
        <p className="dm-fussnote">
          Die gefahrene Strecke schreibt der Server bei jeder Änderung des Kilometerstands fort und
          rechnet sie immer dem gerade montierten Satz zu.
        </p>
      </Tile>

      {fahrzeug.reifen.archiv.length > 0 && (
        <Tile>
          <span className="ads-eyebrow">Archiv</span>
          {fahrzeug.reifen.archiv.map((eintrag) => (
            <ArchivZeile key={eintrag.id} eintrag={eintrag} />
          ))}
        </Tile>
      )}
    </>
  )
}

function ArchivZeile({ eintrag }: { eintrag: ReifenArchivEintrag }) {
  const { api } = useDaten()
  const [bearbeiten, setzeBearbeiten] = useState(false)
  const [laeuft, setzeLaeuft] = useState(false)
  const [form, setzeForm] = useState(() => ({
    ersetzt_am: eintrag.ersetzt_am,
    km: String(eintrag.km ?? ""),
    marke: eintrag.marke ?? "",
    modell: eintrag.modell ?? "",
    dot: eintrag.dot ?? "",
    mass: eintrag.mass ?? "",
    druck_vorne: eintrag.druck_vorne ?? "",
    druck_hinten: eintrag.druck_hinten ?? "",
    kommentar: eintrag.kommentar ?? "",
  }))

  const speichern = async () => {
    setzeLaeuft(true)
    try {
      const kmZahl = Number(form.km.replace(",", "."))
      await api.reifenArchivAktualisieren(eintrag.id, {
        ersetzt_am: form.ersetzt_am,
        km: Number.isFinite(kmZahl) ? kmZahl : null,
        marke: form.marke || null,
        modell: form.modell || null,
        dot: form.dot || null,
        mass: form.mass || null,
        druck_vorne: form.druck_vorne || null,
        druck_hinten: form.druck_hinten || null,
        kommentar: form.kommentar || null,
      })
      setzeBearbeiten(false)
    } finally {
      setzeLaeuft(false)
    }
  }

  const loeschen = async () => {
    if (!bestaetigen("Diesen archivierten Reifensatz löschen?")) return
    setzeLaeuft(true)
    try {
      await api.reifenArchivLoeschen(eintrag.id)
    } finally {
      setzeLaeuft(false)
    }
  }

  return (
    <Accordion
      title={eintrag.satz === "winter" ? "Winterräder" : "Sommerräder"}
      summary={
        // km in derselben Größe/Farbe wie der Titel (nicht als angehängte
        // .ads-acc-h__v-Kleinschrift ans Datum gequetscht - live beobachtet,
        // dass das schwer lesbar war), Datum als eigene, kleinere Zeile
        // darunter. Parität zum Panel (dieselbe Umstellung dort).
        <span style={{ display: "flex", flexDirection: "column", alignItems: "flex-end", gap: 3 }}>
          <span style={{ color: "var(--fg)", fontSize: 15 }}>{deOderStrich(eintrag.km)} km</span>
          <small>Ersetzt am {datum(eintrag.ersetzt_am)}</small>
        </span>
      }
    >
      {bearbeiten ? (
        <>
          <Feld label="Ersetzt am">
            <input
              className="dm-eingabe"
              type="date"
              value={form.ersetzt_am}
              onChange={(e) => setzeForm({ ...form, ersetzt_am: e.target.value })}
            />
          </Feld>
          <Feld label="Gefahrene Strecke" unit="km">
            <input
              className="dm-eingabe"
              inputMode="decimal"
              value={form.km}
              onChange={(e) => setzeForm({ ...form, km: e.target.value })}
            />
          </Feld>
          <Feld label="Marke">
            <input
              className="dm-eingabe"
              value={form.marke}
              onChange={(e) => setzeForm({ ...form, marke: e.target.value })}
            />
          </Feld>
          <Feld label="Modell">
            <input
              className="dm-eingabe"
              value={form.modell}
              onChange={(e) => setzeForm({ ...form, modell: e.target.value })}
            />
          </Feld>
          <Feld label="DOT">
            <input
              className="dm-eingabe"
              value={form.dot}
              onChange={(e) => setzeForm({ ...form, dot: e.target.value })}
            />
          </Feld>
          <Feld label="Größe">
            <input
              className="dm-eingabe"
              value={form.mass}
              onChange={(e) => setzeForm({ ...form, mass: e.target.value })}
            />
          </Feld>
          <Feld label="Luftdruck vorne" unit="bar">
            <input
              className="dm-eingabe"
              value={form.druck_vorne}
              onChange={(e) => setzeForm({ ...form, druck_vorne: e.target.value })}
            />
          </Feld>
          <Feld label="Luftdruck hinten" unit="bar">
            <input
              className="dm-eingabe"
              value={form.druck_hinten}
              onChange={(e) => setzeForm({ ...form, druck_hinten: e.target.value })}
            />
          </Feld>
          {/* Kein <Feld> hier (Label und Eingabe teilen sich sonst eine Zeile,
              die Eingabe bleibt auf ihrer intrinsischen Breite - für eine
              Notiz wie "Profiltiefe 5,1 mm bei der letzten Kontrolle" zu
              wenig Platz, live beobachtet). Eingabe über die volle Breite,
              Label darüber - Parität zum Panel (.feld--breit). */}
          <div className="ads-feld" style={{ display: "block", borderBottom: 0 }}>
            <label style={{ display: "block", marginBottom: 8 }}>Notiz</label>
            <input
              className="dm-eingabe"
              style={{ width: "100%", textAlign: "left" }}
              value={form.kommentar}
              onChange={(e) => setzeForm({ ...form, kommentar: e.target.value })}
            />
          </div>
          <div style={{ display: "flex", gap: 10, marginTop: 14 }}>
            <ActionButton onClick={() => void speichern()} disabled={laeuft}>
              {laeuft ? "Speichere …" : "Speichern"}
            </ActionButton>
            <ActionButton onClick={() => setzeBearbeiten(false)} disabled={laeuft}>
              Abbrechen
            </ActionButton>
          </div>
          <div style={{ marginTop: 10 }}>
            <ActionButton variant="destructive" onClick={() => void loeschen()} disabled={laeuft}>
              Löschen
            </ActionButton>
          </div>
        </>
      ) : (
        <>
          <Werteliste
            kinder={
              <>
                <Wertzeile label="Größe" wert={eintrag.mass || "—"} />
                <Wertzeile
                  label="Marke und Modell"
                  wert={[eintrag.marke, eintrag.modell].filter(Boolean).join(" ") || "—"}
                />
                <Wertzeile label="DOT" wert={eintrag.dot || "—"} />
                <Wertzeile
                  label="Luftdruck"
                  wert={`${eintrag.druck_vorne || "—"} / ${eintrag.druck_hinten || "—"} bar`}
                  zusatz="vorne / hinten"
                />
                {Boolean(eintrag.kommentar) && <Wertzeile label="Notiz" wert={eintrag.kommentar!} />}
              </>
            }
          />
          <div style={{ marginTop: 14 }}>
            <ActionButton onClick={() => setzeBearbeiten(true)}>Bearbeiten</ActionButton>
          </div>
        </>
      )}
    </Accordion>
  )
}
