import json
from pathlib import Path
from typing import Protocol

import requests

from planemapper.constants import DUMP1090_URL, FETCH_TIMEOUT_S
from planemapper.models import Aircraft


class FetcherInterface(Protocol):
    def fetch(self) -> list[Aircraft]: ...


def _parse_aircraft(entry: dict) -> Aircraft:
    raw_alt = entry.get("altitude", 0)
    altitude_ft = int(raw_alt) if isinstance(raw_alt, int) else 0
    return Aircraft(
        icao=entry["hex"],
        lat=float(entry["lat"]),
        lon=float(entry["lon"]),
        heading=float(entry.get("track", 0.0)),
        altitude_ft=altitude_ft,
        callsign=entry.get("flight", "").strip(),
        category=entry.get("category", ""),
        is_mlat=bool(entry.get("mlat")),
        is_stale=False,
    )


class HttpFetcher:
    def fetch(self) -> list[Aircraft]:
        resp = requests.get(DUMP1090_URL, timeout=FETCH_TIMEOUT_S)
        resp.raise_for_status()
        data = resp.json()
        return [_parse_aircraft(e) for e in data.get("aircraft", []) if "lat" in e and "lon" in e]


class FileFixtureFetcher:
    def __init__(self, path: Path) -> None:
        self._path = path

    def fetch(self) -> list[Aircraft]:
        with self._path.open() as f:
            data = json.load(f)
        return [_parse_aircraft(e) for e in data.get("aircraft", []) if "lat" in e and "lon" in e]
