"""Fahrterkennung über den Zündungs-/ACC-Status des FMM003 (§7.1).

Start: die Zündungs-Entität (einstellungen.ZUENDUNG_SENSOR) wechselt auf
"on". Ende: sie wechselt auf "off" und kommt binnen der Pausenzeit nicht
zurück.

2026-08-12: ersetzt die frühere WLAN-basierte Erkennung (Vergleich des vom
iPhone gemeldeten verbundenen WLANs gegen den im Fahrzeugprofil hinterlegten
Namen) - die Zündung ist ein direkteres, von jeder Companion-App-Eigenheit
unabhängiges Signal.

Die Pausenregel wird über task.unique() umgesetzt: jede neue Änderung der
Zündungs-Entität killt eine noch laufende, wartende Bestätigung des
vorherigen Ereignisses. Kommt die Zündung während der Wartezeit zurück, wird
dadurch die wartende Ende-Bestätigung automatisch abgebrochen, ohne dass die
Fahrt beendet wird - das entspricht der Pausenregel aus §7.1.

Die Entity-IDs stehen zentral in pyscript/modules/einstellungen.py - dort vor
der Installation einmalig anpassen (siehe INSTALL.md), oder über das
Setup-Menü in der Oberfläche zuordnen (siehe entitaeten.py; Änderungen dort
wirken für DIESEN Trigger allerdings erst nach einem Neustart, da
@state_trigger die Entity-ID einmalig beim Modul-Laden einliest).

EINSCHRÄNKUNG: der Zustand einer laufenden Fahrt (_fahrt_start_ts) lebt nur
im Arbeitsspeicher dieses Skripts. Ein HA-Neustart mitten in einer Fahrt oder
während der Wartezeit verliert diesen Zwischenstand - die Fahrt würde dann
nicht aufgezeichnet. Das ist ein bekannter Punkt für eine spätere Härtung
(z. B. Zwischenstand in einer input_datetime-Helper-Entität sichern), hier
bewusst nicht mitgebaut, um die Kernlogik nicht zu verkomplizieren, bevor sie
sich im echten Betrieb bewährt hat.
"""

import datetime

import einstellungen
import fahrtabschluss_logik
import frontend_veroeffentlichung
import profil

_fahrt_start_ts = None


def _pausenzeit_sekunden():
    p = profil.profil_lesen()
    return p.get("einstellungen", {}).get("fahrten_pausenzeit_min", 15) * 60


@time_trigger("startup")
def beim_start():
    profil.ordner_sicherstellen()


# Ohne konfigurierte Zündungs-Entität keinen Trigger registrieren - eine
# leere Entity-ID als @state_trigger-Ausdruck ist ungetestetes Verhalten
# (siehe zustand_oder_none()-Kommentar in frontend_veroeffentlichung.py zur
# Grundhaltung "kein geratener Wert"), hier stattdessen ganz weggelassen.
if einstellungen.ZUENDUNG_SENSOR:
    @state_trigger(f"{einstellungen.ZUENDUNG_SENSOR}")
    def zuendung_geaendert(value=None, old_value=None):
        # Killt eine noch laufende Ende-Bestätigung aus einer vorherigen
        # Änderung - das ist der Mechanismus hinter der Pausenregel.
        task.unique("audi_dashboard_fahrt_ende_pruefung")

        global _fahrt_start_ts
        an_jetzt = (value == "on")
        an_vorher = (old_value == "on")

        if an_jetzt and not an_vorher:
            if _fahrt_start_ts is None:
                _fahrt_start_ts = datetime.datetime.now(datetime.timezone.utc)
                log.info(f"audi_dashboard: Fahrt gestartet um {_fahrt_start_ts.isoformat()}")
            return

        if an_vorher and not an_jetzt and _fahrt_start_ts is not None:
            start_ts = _fahrt_start_ts
            abbruch_ts = datetime.datetime.now(datetime.timezone.utc)
            wartezeit_s = _pausenzeit_sekunden()

            # task.unique() oben markiert diese Ausführung als die aktuell
            # gültige. Kommt die Zündung vor Ablauf der Wartezeit zurück,
            # ruft der nächste Trigger erneut task.unique() auf und killt
            # genau diesen task.sleep() - der Code danach läuft dann nie.
            task.sleep(wartezeit_s)

            _fahrt_beenden(start_ts, abbruch_ts)


def _fahrt_beenden(start_ts, ende_ts):
    global _fahrt_start_ts
    dauer_s = int((ende_ts - start_ts).total_seconds())

    fahrt = {
        "trip_id": profil.neue_id("t"),
        "ts_start": start_ts.isoformat(),
        "ts_end": ende_ts.isoformat(),
        "duration_s": dauer_s,
        "distance_km": None,
        "km_quelle": None,
        "odo_start": None,
        "odo_end": None,
        "avg_speed_kmh": None,
        "start_lat": None,
        "start_lon": None,
        "end_lat": None,
        "end_lon": None,
        "start_address": None,
        "end_address": None,
        "art": "privat",
        "route": None,
        "pausen": [],
        "source": "ha",
        "status": "offen",
        "edited_fields": [],
    }
    profil.fahrt_anhaengen(fahrt)
    frontend_veroeffentlichung.fahrten_veroeffentlichen()
    log.info(f"audi_dashboard: Fahrt {fahrt['trip_id']} beendet, Status 'offen', Screening angestoßen")

    _fahrt_start_ts = None
    fahrtabschluss_logik.screening_durchfuehren(einstellungen.KM_SENSOR)


@service
def audi_dashboard_fahrt_manuell_anlegen(ts_start=None, ts_end=None, art="privat"):
    """Manuelle Fahrterfassung aus der Oberfläche (§5.3), unabhängig von der
    automatischen Zündungs-Erkennung. Aufruf als pyscript.audi_dashboard_fahrt_manuell_anlegen."""
    start_ts = datetime.datetime.fromisoformat(ts_start)
    ende_ts = datetime.datetime.fromisoformat(ts_end)
    dauer_s = int((ende_ts - start_ts).total_seconds())
    fahrt = {
        "trip_id": profil.neue_id("t"),
        "ts_start": start_ts.isoformat(),
        "ts_end": ende_ts.isoformat(),
        "duration_s": dauer_s,
        "distance_km": None,
        "km_quelle": None,
        "odo_start": None,
        "odo_end": None,
        "avg_speed_kmh": None,
        "start_lat": None,
        "start_lon": None,
        "end_lat": None,
        "end_lon": None,
        "start_address": None,
        "end_address": None,
        "art": art,
        "route": None,
        "pausen": [],
        "source": "manual",
        "status": "offen",
        "edited_fields": [],
    }
    profil.fahrt_anhaengen(fahrt)
    frontend_veroeffentlichung.fahrten_veroeffentlichen()
    fahrtabschluss_logik.screening_durchfuehren(einstellungen.KM_SENSOR)


@service
def audi_dashboard_fahrt_loeschen(trip_id=None):
    """Löscht eine Fahrt unwiderruflich (Löschfunktion in der Oberfläche,
    §Löschfunktion). Aufruf als pyscript.audi_dashboard_fahrt_loeschen."""
    if not trip_id:
        log.warning("audi_dashboard: fahrt_loeschen ohne trip_id aufgerufen")
        return
    if profil.fahrt_loeschen(trip_id):
        frontend_veroeffentlichung.fahrten_veroeffentlichen()
        log.info(f"audi_dashboard: Fahrt {trip_id} gelöscht")
    else:
        log.warning(f"audi_dashboard: Fahrt {trip_id} nicht gefunden")
