"""OpenSky Network API Client — Live Flight Tracking ohne API-Key."""

import httpx

from src.config import settings


class OpenSkyClient:
    """Async-Client für die OpenSky Network API (Flugverfolgung in Echtzeit).

    Rate-Limit: 100 Calls/Tag (anonym, ohne Account).
    Die API liefert Flugzustände als Arrays, nicht als Objekte.

    State-Array-Indizes:
        0: icao24          — ICAO24-Adresse des Transponders
        1: callsign        — Callsign (kann leer sein)
        2: origin_country  — Herkunftsland
        3: time_position   — Unix-Timestamp der letzten Position
        4: last_contact     — Unix-Timestamp des letzten Kontakts
        5: longitude       — Längengrad (WGS84)
        6: latitude        — Breitengrad (WGS84)
        7: baro_altitude   — Barometrische Höhe in Metern
        8: on_ground       — Ob das Flugzeug am Boden ist
        9: velocity        — Geschwindigkeit in m/s
        10: true_track     — Kurs in Grad (Nordrichtung = 0°)
        11: vertical_rate  — Vertikalgeschwindigkeit in m/s
        12: sensors        — IDs der empfangenden Sensoren
        13: geo_altitude   — Geometrische Höhe in Metern
        14: squawk         — Transponder-Code
        15: spi            — Ob Special Position Identification aktiv
        16: position_source — Quelle der Position (0=ADS-B, 1=ASTERIX, 2=MLAT, 3=FLARM)
    """

    # Lesbare Feldnamen für State-Arrays
    STATE_FIELDS = [
        "icao24", "callsign", "origin_country", "time_position",
        "last_contact", "longitude", "latitude", "baro_altitude",
        "on_ground", "velocity", "true_track", "vertical_rate",
        "sensors", "geo_altitude", "squawk", "spi", "position_source",
    ]

    def __init__(self):
        self._client = httpx.AsyncClient(timeout=settings.http_timeout)
        self._base = settings.opensky_base_url

    def _parse_state(self, state: list) -> dict:
        """Ein State-Array in ein lesbares Dictionary umwandeln."""
        result = {}
        for i, field in enumerate(self.STATE_FIELDS):
            if i < len(state):
                value = state[i]
                # Callsign bereinigen (Leerzeichen entfernen)
                if field == "callsign" and isinstance(value, str):
                    value = value.strip()
                result[field] = value
        return result

    async def get_all_states(
        self,
        lamin: float | None = None,
        lomin: float | None = None,
        lamax: float | None = None,
        lomax: float | None = None,
    ) -> dict:
        """Alle aktuellen Flugzustände abrufen, optional auf Gebiet begrenzt.

        Args:
            lamin: Minimaler Breitengrad (südliche Grenze)
            lomin: Minimaler Längengrad (westliche Grenze)
            lamax: Maximaler Breitengrad (nördliche Grenze)
            lomax: Maximaler Längengrad (östliche Grenze)
        """
        url = f"{self._base}/states/all"
        params = {}
        if all(v is not None for v in [lamin, lomin, lamax, lomax]):
            params.update({
                "lamin": lamin,
                "lomin": lomin,
                "lamax": lamax,
                "lomax": lomax,
            })
        resp = await self._client.get(url, params=params)
        resp.raise_for_status()
        return resp.json()

    async def get_states_by_icao24(self, icao24: str) -> dict:
        """Flugzustand eines bestimmten Flugzeugs über ICAO24-Adresse."""
        url = f"{self._base}/states/all"
        params = {"icao24": icao24.lower()}
        resp = await self._client.get(url, params=params)
        resp.raise_for_status()
        return resp.json()

    async def get_arrivals(self, airport: str, begin: int, end: int) -> list:
        """Ankünfte an einem Flughafen in einem Zeitraum.

        Args:
            airport: ICAO-Code des Flughafens (z.B. EDDF)
            begin: Unix-Timestamp für Beginn des Zeitraums
            end: Unix-Timestamp für Ende des Zeitraums
        """
        url = f"{self._base}/flights/arrival"
        params = {"airport": airport.upper(), "begin": begin, "end": end}
        resp = await self._client.get(url, params=params)
        resp.raise_for_status()
        return resp.json()

    async def get_departures(self, airport: str, begin: int, end: int) -> list:
        """Abflüge von einem Flughafen in einem Zeitraum.

        Args:
            airport: ICAO-Code des Flughafens (z.B. EDDF)
            begin: Unix-Timestamp für Beginn des Zeitraums
            end: Unix-Timestamp für Ende des Zeitraums
        """
        url = f"{self._base}/flights/departure"
        params = {"airport": airport.upper(), "begin": begin, "end": end}
        resp = await self._client.get(url, params=params)
        resp.raise_for_status()
        return resp.json()

    async def get_track(self, icao24: str, time: int = 0) -> dict:
        """Flugpfad eines Flugzeugs abrufen.

        Args:
            icao24: ICAO24-Adresse des Transponders
            time: Unix-Timestamp (0 = aktuellster Track)
        """
        url = f"{self._base}/tracks/all"
        params = {"icao24": icao24.lower(), "time": time}
        resp = await self._client.get(url, params=params)
        resp.raise_for_status()
        return resp.json()

    async def close(self):
        """HTTP-Client schließen."""
        await self._client.aclose()
