/**
 * Tankvorgänge, nach Jahr und Monat aufklappbar. Vorlage: `vFuel()`.
 *
 * Der Durchschnittspreis ist immer mengengewichtet (Summe Kosten geteilt durch
 * Summe Liter) — eine kleine teure Tankung darf den Schnitt nicht so stark
 * heben wie eine große.
 */

import { useState } from "react"

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

import { useDaten } from "../daten/DatenKontext"
import { nachJahrUndMonat } from "../daten/statistik"
import { datum, de, deOderStrich, eur, monatJahr, schnittpreis, summe } from "../format"
import type { SeitenName } from "../navigation"
import { Leerzustand } from "./bausteine"
import { Zeilenmenue } from "./Zeilenmenue"

export function Tanken({ geheZu }: { geheZu: (name: SeitenName, id?: string) => void }) {
  const { tankvorgaenge, api } = useDaten()
  const [formularOffen, setzeFormularOffen] = useState(false)

  const gruppen = nachJahrUndMonat(tankvorgaenge, (t) => t.ts)

  return (
    <>
      <div className="dm-abschnitt">
        <span className="ads-eyebrow">
          {tankvorgaenge.length === 0
            ? "Keine Tankvorgänge"
            : `${de(tankvorgaenge.length)} Tankvorgang${tankvorgaenge.length === 1 ? "" : "̈e"}`}
        </span>
        <button
          type="button"
          className="dm-textknopf"
          onClick={() => setzeFormularOffen((offen) => !offen)}
        >
          {formularOffen ? "Abbrechen" : "Tankung eintragen"}
        </button>
      </div>

      {formularOffen && <TankFormular beiFertig={() => setzeFormularOffen(false)} />}

      {tankvorgaenge.length === 0 && !formularOffen && (
        <Leerzustand
          titel="Noch keine Tankvorgänge"
          text="Die App erkennt Tankungen automatisch am steigenden Füllstand und vervollständigt sie aus dem hochgeladenen Beleg. Du kannst sie auch selbst eintragen."
          aktion={{ beschriftung: "Tankung eintragen", beiKlick: () => setzeFormularOffen(true) }}
        />
      )}

      {gruppen.map((jahr) => (
        <Accordion
          key={jahr.jahr}
          title={String(jahr.jahr)}
          summary={`${eur(summe(jahr.eintraege, (t) => t.fuel_total_eur ?? 0))} €`}
          defaultOpen={jahr === gruppen[0]}
        >
          {jahr.monate.map((monat) => {
            const schnitt = schnittpreis(monat.eintraege)
            return (
              <Accordion
                key={monat.schluessel}
                level={2}
                title={monatJahr(new Date(monat.jahr, monat.monat, 1))}
                summary={schnitt > 0 ? `${eur(schnitt)} €/l` : "—"}
                defaultOpen={monat === jahr.monate[0]}
              >
                {monat.eintraege.map((tank) => (
                  <Zeilenmenue
                    key={tank.tank_id}
                    loeschFrage={`Tankvorgang vom ${datum(tank.ts)} löschen?`}
                    beiLoeschen={() => void api.tankvorgangLoeschen(tank.tank_id)}
                    kinder={
                      <button
                        type="button"
                        className="dm-listenzeile"
                        onClick={() => geheZu("fill", tank.tank_id)}
                      >
                        <span className="dm-listenzeile__haupt">
                          <span className="dm-listenzeile__titel">
                            {deOderStrich(tank.liters, 2)} l
                            {tank.fuel_total_eur != null && (
                              <span className="dm-listenzeile__neben">
                                {eur(tank.fuel_total_eur)} €
                              </span>
                            )}
                          </span>
                          <span className="dm-listenzeile__unter">
                            {datum(tank.ts)}
                            {tank.station_name ? ` · ${tank.station_name}` : ""}
                            {tank.price_per_l != null ? ` · ${eur(tank.price_per_l)} €/l` : ""}
                          </span>
                        </span>
                        {tank.status === "unvollständig" && <Pill>unvollständig</Pill>}
                      </button>
                    }
                  />
                ))}
              </Accordion>
            )
          })}
        </Accordion>
      ))}
    </>
  )
}

function TankFormular({ beiFertig }: { beiFertig: () => void }) {
  const { api } = useDaten()
  const [zeitpunkt, setzeZeitpunkt] = useState("")
  const [liter, setzeLiter] = useState("")
  const [kosten, setzeKosten] = useState("")
  const [station, setzeStation] = useState("")
  const [km, setzeKm] = useState("")
  const [fehler, setzeFehler] = useState<string | null>(null)
  const [laeuft, setzeLaeuft] = useState(false)

  const speichern = async () => {
    setzeFehler(null)
    const literZahl = Number(liter.replace(",", "."))
    const kostenZahl = Number(kosten.replace(",", "."))
    if (!Number.isFinite(literZahl) || literZahl <= 0) {
      setzeFehler("Bitte die getankte Menge in Litern angeben.")
      return
    }
    if (!Number.isFinite(kostenZahl) || kostenZahl <= 0) {
      setzeFehler("Bitte den Gesamtbetrag angeben.")
      return
    }
    setzeLaeuft(true)
    try {
      const kmZahl = Number(km.replace(",", "."))
      await api.tankvorgangAnlegen({
        ts: zeitpunkt ? new Date(zeitpunkt).toISOString() : new Date().toISOString(),
        liter: literZahl,
        kosten: kostenZahl,
        station: station || null,
        km: Number.isFinite(kmZahl) && km ? kmZahl : null,
      })
      beiFertig()
    } catch (ursache) {
      setzeFehler(ursache instanceof Error ? ursache.message : String(ursache))
    } finally {
      setzeLaeuft(false)
    }
  }

  return (
    <Tile>
      <span className="ads-eyebrow">Tankung eintragen</span>
      <Feld label="Zeitpunkt">
        <input
          className="dm-eingabe"
          type="datetime-local"
          value={zeitpunkt}
          onChange={(e) => setzeZeitpunkt(e.target.value)}
        />
      </Feld>
      <Feld label="Menge" unit="l">
        <input
          className="dm-eingabe"
          inputMode="decimal"
          placeholder="0,00"
          value={liter}
          onChange={(e) => setzeLiter(e.target.value)}
        />
      </Feld>
      <Feld label="Gesamtbetrag" unit="€">
        <input
          className="dm-eingabe"
          inputMode="decimal"
          placeholder="0,00"
          value={kosten}
          onChange={(e) => setzeKosten(e.target.value)}
        />
      </Feld>
      <Feld label="Tankstelle">
        <input
          className="dm-eingabe"
          placeholder="optional"
          value={station}
          onChange={(e) => setzeStation(e.target.value)}
        />
      </Feld>
      <Feld label="Kilometerstand" unit="km" last>
        <input
          className="dm-eingabe"
          inputMode="numeric"
          placeholder="vom Fahrzeug"
          value={km}
          onChange={(e) => setzeKm(e.target.value)}
        />
      </Feld>
      {fehler && (
        <p className="dm-fehler" role="alert">
          {fehler}
        </p>
      )}
      <p className="dm-fussnote">
        Den Preis je Liter rechnet die App selbst aus Betrag und Menge — er wird nie aus einem Beleg
        übernommen. Ohne Kilometerstand nimmt sie den des Fahrzeugs.
      </p>
      <div style={{ marginTop: 14 }}>
        <ActionButton onClick={() => void speichern()} disabled={laeuft}>
          {laeuft ? "Speichere …" : "Speichern"}
        </ActionButton>
      </div>
    </Tile>
  )
}
