/**
 * Übersetzt das Fahrzeugprofil des Backends in die Form, mit der die
 * Oberfläche arbeitet — und wieder zurück.
 *
 * Aus dem alten Panel portiert (`profilZuConfig`/`profilZuCar`/
 * `configCarZuProfil`). Die Rechenregeln sind unverändert übernommen; nur die
 * Typen sind neu, weil das Panel ohne auskam.
 */

import type { Fahrzeugstatus, Profil, SicherheitsPunkt } from "../api"
import { isoTag } from "../format"

export interface Einstellungen {
  fahrzeugtitel: string
  fahrzeugzusatz: string
  fahrzeuguntertitel: string
  kennzeichen: string
  startbild: string
  tankvolumen: number
  nachtVon: string
  nachtBis: string
  pauseMin: number
  markenname: string
  backupIntervall: string
  letztesBackup: string | null
  ausfuehrung: string
}

export interface Reifensatz {
  km?: number | null
  groesse?: string | null
  marke?: string | null
  modell?: string | null
  dot?: string | null
  profiltiefe_mm?: number | null
  [weitere: string]: unknown
}

export interface Fahrzeug {
  fin: string
  details: string
  erstzulassung: string
  hu: string
  odo: number
  odoBekannt: boolean
  tankPct: number
  reichweite: number | null
  batteriespannung: number | null
  gesichert: boolean | null
  sicherheitscheck: SicherheitsPunkt[]
  /** Zündung an = das Fahrzeug fährt gerade. `null` heißt „kein
      Zündungssensor zugeordnet", also unbekannt — nicht „steht". */
  zuendung: boolean | null
  standortLat: number | null
  standortLon: number | null
  standortZeit: string | null
  oelwechselFaelligTs: string | null
  oelwechselFaelligKm: number | null
  inspektionFaelligTs: string | null
  inspektionFaelligKm: number | null
  smartdeal: { aktiv: boolean; laeuftAb: string | null }
  oel: {
    modus: string
    km: number | null
    monate: number | null
    herstellerKm: number | null
    herstellerMonate: number | null
  }
  versicherung: Record<string, unknown>
  steuer: Record<string, unknown> & { faellig: string }
  reifen: {
    aktiv: "Sommer" | "Winter"
    anzugsmoment: number | null
    wechsel: Record<string, unknown>
    sommer: Reifensatz
    winter: Reifensatz
  }
  service: Record<string, unknown>
  technik: Record<string, unknown>
  ausstattung: unknown
}

/**
 * Liest einen Abschnitt des Profils **als Kopie**.
 *
 * Die Kopie ist der Punkt: Ohne sie bekämen die Screens lebende Verweise ins
 * Rohprofil, und eine Bearbeitung im Formular würde den Rohstand still
 * mitverändern. Damit wäre er als Vergleichsbasis wertlos — und die Zusage,
 * den vom Backend fortgeschriebenen Reifen-Kilometerstand nie zu
 * überschreiben, ließe sich nicht mehr halten.
 */
function abschnitt(profil: Profil, name: string): Record<string, unknown> {
  const wert = profil[name]
  if (!wert || typeof wert !== "object") return {}
  return structuredClone(wert) as Record<string, unknown>
}

function text(quelle: Record<string, unknown>, feld: string, ersatz = ""): string {
  const wert = quelle[feld]
  return typeof wert === "string" ? wert : ersatz
}

function zahl(quelle: Record<string, unknown>, feld: string): number | null {
  const wert = quelle[feld]
  return typeof wert === "number" ? wert : null
}

export function profilZuEinstellungen(profil: Profil): Einstellungen {
  const fahrzeug = abschnitt(profil, "fahrzeug")
  const einst = abschnitt(profil, "einstellungen")
  return {
    fahrzeugtitel: text(fahrzeug, "titel"),
    fahrzeugzusatz: text(fahrzeug, "zusatz"),
    fahrzeuguntertitel: text(fahrzeug, "untertitel"),
    kennzeichen: text(fahrzeug, "kennzeichen"),
    startbild: text(einst, "uebersichtsbild", "seitenansicht.webp"),
    tankvolumen: zahl(fahrzeug, "tankvolumen_liter") ?? 58,
    nachtVon: text(einst, "nacht_von", "22:00"),
    nachtBis: text(einst, "nacht_bis", "06:00"),
    pauseMin: zahl(einst, "fahrten_pausenzeit_min") ?? 15,
    markenname: text(einst, "kraftstoffanbieter", "Shell"),
    backupIntervall: text(einst, "backup_intervall", "aus"),
    letztesBackup: text(einst, "letztes_backup") || null,
    ausfuehrung: text(fahrzeug, "ausfuehrung"),
  }
}

export function profilZuFahrzeug(profil: Profil, status: Fahrzeugstatus): Fahrzeug {
  const fahrzeug = abschnitt(profil, "fahrzeug")
  const einst = abschnitt(profil, "einstellungen")
  // Bereits eine Kopie (siehe abschnitt()), darf also gefahrlos weitergereicht
  // und von den Formularen bearbeitet werden.
  const reifen = abschnitt(profil, "reifen")
  const saetze = (reifen["saetze"] ?? {}) as Record<string, Reifensatz>
  const smartdeal = (einst["smartdeal"] ?? {}) as Record<string, unknown>
  const oel = (einst["oelwechsel_intervall"] ?? {}) as Record<string, unknown>
  const steuer = abschnitt(profil, "steuer")

  const laeuftAb = typeof smartdeal["laeuft_ab"] === "string" ? (smartdeal["laeuft_ab"] as string) : null

  return {
    fin: text(fahrzeug, "fin"),
    details: text(fahrzeug, "details"),
    erstzulassung: text(fahrzeug, "erstzulassung"),
    hu: text(fahrzeug, "hauptuntersuchung_faellig"),
    odo: status.km ?? 0,
    odoBekannt: status.km !== null && status.km !== undefined,
    tankPct: status.tankprozent ?? 0,
    reichweite: status.reichweite_km ?? null,
    batteriespannung: status.batteriespannung ?? null,
    gesichert: status.gesichert ?? null,
    sicherheitscheck: status.sicherheitscheck ?? [],
    zuendung: status.zuendung ?? null,
    standortLat: status.standort_lat ?? null,
    standortLon: status.standort_lon ?? null,
    standortZeit: status.standort_zeit ?? null,
    oelwechselFaelligTs: status.oelwechsel_faellig_ts ?? null,
    oelwechselFaelligKm: status.oelwechsel_faellig_km ?? null,
    inspektionFaelligTs: status.inspektion_faellig_ts ?? null,
    inspektionFaelligKm: status.inspektion_faellig_km ?? null,
    // „Gültig bis" ist einschließlich: der Rabatt gilt noch am Stichtag selbst,
    // erst am Folgetag schaltet er ab. Unverändert aus dem alten Panel.
    smartdeal: {
      aktiv: smartdeal["aktiv"] === true && (!laeuftAb || laeuftAb >= isoTag()),
      laeuftAb,
    },
    oel: {
      modus: text(oel, "modus", "hersteller"),
      km: zahl(oel, "km"),
      monate: zahl(oel, "monate"),
      herstellerKm: zahl(oel, "hersteller_km"),
      herstellerMonate: zahl(oel, "hersteller_monate"),
    },
    versicherung: abschnitt(profil, "versicherung"),
    steuer: { ...steuer, faellig: text(steuer, "faellig") },
    reifen: {
      aktiv: reifen["aktiv"] === "winter" ? "Winter" : "Sommer",
      anzugsmoment: zahl(reifen, "anzugsmoment_nm"),
      wechsel: (reifen["wechsel"] ?? {}) as Record<string, unknown>,
      sommer: saetze["sommer"] ?? {},
      winter: saetze["winter"] ?? {},
    },
    service: abschnitt(profil, "service"),
    technik: abschnitt(profil, "technik"),
    // Als Einzige eine Liste statt eines Objekts, deshalb eigens kopiert.
    ausstattung: profil["ausstattung"] ? structuredClone(profil["ausstattung"]) : [],
  }
}

/**
 * Rückrichtung für `audi_dashboard_profil_schreiben`. Das Backend kennt keinen
 * Dienst für einzelne Felder — es wird immer das ganze Profil geschrieben,
 * deshalb wird der zuletzt gelesene Rohstand kopiert und nur das Geänderte
 * überschrieben.
 */
export function zusammenfuehren(
  rohprofil: Profil,
  einstellungen: Einstellungen,
  fahrzeug: Fahrzeug,
): Profil {
  const p = structuredClone(rohprofil) as Profil
  const f = (p["fahrzeug"] ??= {}) as Record<string, unknown>
  const e = (p["einstellungen"] ??= {}) as Record<string, unknown>
  const r = (p["reifen"] ??= {}) as Record<string, unknown>

  f["titel"] = einstellungen.fahrzeugtitel
  f["zusatz"] = einstellungen.fahrzeugzusatz
  f["untertitel"] = einstellungen.fahrzeuguntertitel
  f["kennzeichen"] = einstellungen.kennzeichen
  f["ausfuehrung"] = einstellungen.ausfuehrung
  f["tankvolumen_liter"] = einstellungen.tankvolumen
  f["fin"] = fahrzeug.fin
  f["erstzulassung"] = fahrzeug.erstzulassung
  f["hauptuntersuchung_faellig"] = fahrzeug.hu

  e["uebersichtsbild"] = einstellungen.startbild
  e["fahrten_pausenzeit_min"] = einstellungen.pauseMin
  e["backup_intervall"] = einstellungen.backupIntervall
  e["nacht_von"] = einstellungen.nachtVon
  e["nacht_bis"] = einstellungen.nachtBis
  e["smartdeal"] = { aktiv: fahrzeug.smartdeal.aktiv, laeuft_ab: fahrzeug.smartdeal.laeuftAb }
  e["oelwechsel_intervall"] = {
    modus: fahrzeug.oel.modus,
    km: fahrzeug.oel.km,
    monate: fahrzeug.oel.monate,
    hersteller_km: fahrzeug.oel.herstellerKm,
    hersteller_monate: fahrzeug.oel.herstellerMonate,
  }

  p["versicherung"] = fahrzeug.versicherung
  p["steuer"] = { ...fahrzeug.steuer, faellig: fahrzeug.steuer.faellig || null }
  p["service"] = fahrzeug.service

  r["aktiv"] = fahrzeug.reifen.aktiv.toLowerCase()
  r["anzugsmoment_nm"] = fahrzeug.reifen.anzugsmoment
  r["wechsel"] = fahrzeug.reifen.wechsel
  const saetze = (r["saetze"] ??= {}) as Record<string, Reifensatz>
  for (const name of ["sommer", "winter"] as const) {
    // km bewusst NICHT mitschreiben: das Backend (reifenzaehler.py) schreibt
    // den Wert bei jeder Kilometerstandsänderung fort. Ein im Browser
    // gehaltener älterer Stand würde eine zwischenzeitliche Fortschreibung
    // überschreiben.
    const { km: _km, ...rest } = fahrzeug.reifen[name]
    saetze[name] = { ...(saetze[name] ?? {}), ...rest }
  }

  return p
}
