/**
 * Service, Werkstatt und Servicebuch. Vorlagen: `vService()`, `vWerkstatt()`,
 * `vSbuch()`.
 *
 * Die vom Fahrzeug gemeldete Fälligkeit und die aus dem Servicebuch
 * gerechnete Prognose stehen bewusst nebeneinander statt sich zu ersetzen:
 * Die Logik im Werkscomputer ist nicht bekannt und kann von den selbst
 * eingestellten Intervallen abweichen.
 */

import { useState } from "react"

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

import { useDaten } from "../daten/DatenKontext"
import { oelwechselPrognose } from "../daten/service"
import { datum, de, isoTag } from "../format"
import type { SeitenName } from "../navigation"
import { Leerzustand, NaviKachel, Wertzeile, Werteliste, bestaetigen } from "./bausteine"
import { kalenderDateiLaden } from "./kalender"

export interface ServicebuchEintrag {
  datum?: string
  km?: number
  art?: string
  betrieb?: string
  notiz?: string
  [weitere: string]: unknown
}

interface Autohaus {
  name?: string
  adresse?: string
  tel?: string
  mail?: string
}

export function Service({ geheZu }: { geheZu: (name: SeitenName, id?: string) => void }) {
  const { fahrzeug } = useDaten()
  if (!fahrzeug) return null

  const buch = (fahrzeug.service["buch"] ?? []) as ServicebuchEintrag[]
  const autohaus = (fahrzeug.service["autohaus"] ?? {}) as Autohaus
  const prognose = oelwechselPrognose(fahrzeug, buch)

  return (
    <>
      <Tile>
        <span className="ads-eyebrow">Nächster Ölwechsel</span>
        <Werteliste
          kinder={
            <>
              <Wertzeile
                label="Vom Fahrzeug gemeldet"
                wert={fahrzeug.oelwechselFaelligTs ? datum(fahrzeug.oelwechselFaelligTs) : "—"}
                zusatz={
                  fahrzeug.oelwechselFaelligKm != null
                    ? `in ${de(Math.abs(fahrzeug.oelwechselFaelligKm))} km`
                    : undefined
                }
              />
              <Wertzeile
                label="Eigene Prognose"
                wert={prognose ? datum(prognose.datum) : "—"}
                zusatz={
                  prognose
                    ? `${de(prognose.restKm)} km offen · ${de(prognose.kmProTag, 1)} km/Tag`
                    : "Noch kein Ölwechsel im Servicebuch"
                }
              />
              <Wertzeile
                label="Nächste Inspektion"
                wert={fahrzeug.inspektionFaelligTs ? datum(fahrzeug.inspektionFaelligTs) : "—"}
                zusatz={
                  fahrzeug.inspektionFaelligKm != null
                    ? `in ${de(Math.abs(fahrzeug.inspektionFaelligKm))} km`
                    : undefined
                }
              />
              <Wertzeile
                label="Hauptuntersuchung"
                wert={fahrzeug.hu ? datum(fahrzeug.hu) : "—"}
              />
            </>
          }
        />
        {prognose && (
          <div style={{ marginTop: 14 }}>
            <ActionButton
              onClick={() =>
                kalenderDateiLaden("Ölwechsel", prognose.datum, "Ölwechsel laut eigener Prognose")
              }
            >
              In den Kalender eintragen
            </ActionButton>
          </div>
        )}
        <p className="dm-fussnote">
          Die eigene Prognose rechnet ab dem letzten Ölwechsel im Servicebuch neu und nutzt die
          seither tatsächlich gefahrene Strecke. Sie ersetzt die Meldung des Fahrzeugs nicht,
          sondern ergänzt sie.
        </p>
      </Tile>

      <div className="dm-raster">
        <NaviKachel
          titel="Werkstatt"
          wert={autohaus.name || "Noch nicht hinterlegt"}
          beiKlick={() => geheZu("werkstatt")}
        />
        <NaviKachel
          titel="Servicebuch"
          wert={`${de(buch.length)} Eintrag${buch.length === 1 ? "" : "e"}`}
          beiKlick={() => geheZu("sbuch")}
        />
      </div>
    </>
  )
}

export function Werkstatt() {
  const { fahrzeug, profilSpeichern } = useDaten()
  const autohausRoh = (fahrzeug?.service["autohaus"] ?? {}) as Autohaus
  const [entwurf, setzeEntwurf] = useState<Autohaus>({ ...autohausRoh })
  const [laeuft, setzeLaeuft] = useState(false)
  const [gespeichert, setzeGespeichert] = useState(false)

  if (!fahrzeug) return null

  const speichern = async () => {
    setzeLaeuft(true)
    setzeGespeichert(false)
    try {
      const neu = { ...fahrzeug, service: { ...fahrzeug.service, autohaus: entwurf } }
      await profilSpeichern({ fahrzeug: neu })
      setzeGespeichert(true)
    } finally {
      setzeLaeuft(false)
    }
  }

  const feld = (schluessel: keyof Autohaus, beschriftung: string, letztes = false) => (
    <Feld label={beschriftung} last={letztes}>
      <input
        className="dm-eingabe"
        value={entwurf[schluessel] ?? ""}
        onChange={(e) => setzeEntwurf((alt) => ({ ...alt, [schluessel]: e.target.value }))}
      />
    </Feld>
  )

  return (
    <Tile>
      <span className="ads-eyebrow">Werkstatt</span>
      {feld("name", "Name")}
      {feld("adresse", "Adresse")}
      {feld("tel", "Telefon")}
      {feld("mail", "E-Mail", true)}
      {gespeichert && <p className="dm-erfolg">Gespeichert.</p>}
      <div style={{ marginTop: 14 }}>
        <ActionButton onClick={() => void speichern()} disabled={laeuft}>
          {laeuft ? "Speichere …" : "Speichern"}
        </ActionButton>
      </div>
    </Tile>
  )
}

export function Servicebuch() {
  const { fahrzeug, profilSpeichern } = useDaten()
  const [neuOffen, setzeNeuOffen] = useState(false)
  const [entwurf, setzeEntwurf] = useState<ServicebuchEintrag>({ datum: isoTag(), art: "Ölwechsel" })
  const [laeuft, setzeLaeuft] = useState(false)

  if (!fahrzeug) return null
  const buch = (fahrzeug.service["buch"] ?? []) as ServicebuchEintrag[]

  const schreiben = async (neuesBuch: ServicebuchEintrag[]) => {
    setzeLaeuft(true)
    try {
      await profilSpeichern({
        fahrzeug: { ...fahrzeug, service: { ...fahrzeug.service, buch: neuesBuch } },
      })
    } finally {
      setzeLaeuft(false)
    }
  }

  const hinzufuegen = async () => {
    await schreiben(
      [...buch, entwurf].sort((a, b) => String(b.datum ?? "").localeCompare(String(a.datum ?? ""))),
    )
    setzeNeuOffen(false)
    setzeEntwurf({ datum: isoTag(), art: "Ölwechsel" })
  }

  const entfernen = async (index: number) => {
    if (!bestaetigen("Diesen Servicebuch-Eintrag löschen?")) return
    await schreiben(buch.filter((_, i) => i !== index))
  }

  return (
    <>
      <div className="dm-abschnitt">
        <span className="ads-eyebrow">{de(buch.length)} Einträge</span>
        <button
          type="button"
          className="dm-textknopf"
          onClick={() => setzeNeuOffen((offen) => !offen)}
        >
          {neuOffen ? "Abbrechen" : "Eintrag hinzufügen"}
        </button>
      </div>

      {neuOffen && (
        <Tile>
          <span className="ads-eyebrow">Neuer Eintrag</span>
          <Feld label="Datum">
            <input
              className="dm-eingabe"
              type="date"
              value={entwurf.datum ?? ""}
              onChange={(e) => setzeEntwurf((alt) => ({ ...alt, datum: e.target.value }))}
            />
          </Feld>
          <Feld label="Art">
            <select
              className="dm-auswahl"
              value={entwurf.art ?? "Ölwechsel"}
              onChange={(e) => setzeEntwurf((alt) => ({ ...alt, art: e.target.value }))}
            >
              <option>Ölwechsel</option>
              <option>Inspektion</option>
              <option>Hauptuntersuchung</option>
              <option>Reparatur</option>
              <option>Sonstiges</option>
            </select>
          </Feld>
          <Feld label="Kilometerstand" unit="km">
            <input
              className="dm-eingabe"
              inputMode="numeric"
              value={entwurf.km ?? ""}
              onChange={(e) => setzeEntwurf((alt) => ({ ...alt, km: Number(e.target.value) }))}
            />
          </Feld>
          <Feld label="Betrieb">
            <input
              className="dm-eingabe"
              value={entwurf.betrieb ?? ""}
              onChange={(e) => setzeEntwurf((alt) => ({ ...alt, betrieb: e.target.value }))}
            />
          </Feld>
          <Feld label="Notiz" last>
            <input
              className="dm-eingabe"
              value={entwurf.notiz ?? ""}
              onChange={(e) => setzeEntwurf((alt) => ({ ...alt, notiz: e.target.value }))}
            />
          </Feld>
          <div style={{ marginTop: 14 }}>
            <ActionButton onClick={() => void hinzufuegen()} disabled={laeuft}>
              Speichern
            </ActionButton>
          </div>
        </Tile>
      )}

      {buch.length === 0 && !neuOffen && (
        <Leerzustand
          titel="Servicebuch ist leer"
          text="Trag hier ein, was am Fahrzeug gemacht wurde. Aus den Ölwechseln entsteht die eigene Wartungsprognose."
          aktion={{ beschriftung: "Eintrag hinzufügen", beiKlick: () => setzeNeuOffen(true) }}
        />
      )}

      {buch.map((eintrag, index) => (
        <Tile key={`${eintrag.datum}-${index}`}>
          <div className="dm-detail__kopf">
            <div>
              <span className="ads-eyebrow">{eintrag.datum ? datum(eintrag.datum) : "ohne Datum"}</span>
              <div style={{ fontSize: 17, fontWeight: 300, marginTop: 4 }}>
                {eintrag.art ?? "Eintrag"}
              </div>
            </div>
            <button
              type="button"
              className="dm-textknopf"
              onClick={() => void entfernen(index)}
              disabled={laeuft}
            >
              Löschen
            </button>
          </div>
          <Werteliste
            kinder={
              <>
                <Wertzeile
                  label="Kilometerstand"
                  wert={eintrag.km != null ? `${de(eintrag.km)} km` : "—"}
                />
                <Wertzeile label="Betrieb" wert={eintrag.betrieb || "—"} />
                {eintrag.notiz && <Wertzeile label="Notiz" wert={eintrag.notiz} />}
              </>
            }
          />
        </Tile>
      ))}
    </>
  )
}
