from __future__ import annotations

from pydantic import BaseModel, ConfigDict


class AirportInfo(BaseModel):
    model_config = ConfigDict(extra="ignore")

    name: str = ""
    city: str = ""
    iata: str = ""


class Endpoint(BaseModel):
    model_config = ConfigDict(extra="ignore")

    when: str = ""
    airport: str = ""
    airport_info: AirportInfo | None = None


class Aircraft(BaseModel):
    model_config = ConfigDict(extra="ignore")

    model: str = ""
    manufacturer: str = ""


class Connection(BaseModel):
    model_config = ConfigDict(extra="ignore")

    departure: Endpoint = Endpoint()
    arrival: Endpoint = Endpoint()
    airline: str = ""
    flight: list[str] = []
    cabin: str = ""
    aircraft: Aircraft | None = None
    times: dict | None = None

    @property
    def departure_airport(self) -> str:
        return self.departure.airport

    @property
    def arrival_airport(self) -> str:
        return self.arrival.airport

    @property
    def flight_number(self) -> str:
        return self.flight[0] if self.flight else ""


class TransferOption(BaseModel):
    model_config = ConfigDict(extra="ignore")

    program: str = ""
    program_key: str = ""
    miles: int = 0


class Payment(BaseModel):
    model_config = ConfigDict(extra="ignore")

    currency: str = "USD"
    taxes: float = 0.0
    fees: float = 0.0


class Fare(BaseModel):
    model_config = ConfigDict(extra="ignore")

    miles: int = 0
    program: str = ""
    program_key: str = ""
    payment: Payment = Payment()
    transfer: list[TransferOption] = []

    @property
    def program_name(self) -> str:
        return self.program

    @property
    def taxes(self) -> float:
        return self.payment.taxes

    @property
    def fees(self) -> float:
        return self.payment.fees


class Times(BaseModel):
    model_config = ConfigDict(extra="ignore")

    flight: str = "0:0"
    layover: str = "0:0"


class Route(BaseModel):
    model_config = ConfigDict(extra="ignore")

    ulid: str = ""
    num_stops: int = 0
    times: Times = Times()
    fares: list[Fare] = []
    connections: list[Connection] = []

    @property
    def stops(self) -> int:
        return self.num_stops

    @property
    def flight_time_minutes(self) -> int | None:
        return _parse_time(self.times.flight)

    @property
    def layover_time_minutes(self) -> int | None:
        return _parse_time(self.times.layover)


class SearchResult(BaseModel):
    model_config = ConfigDict(extra="ignore")

    routes: list[Route] = []


class RoundtripResults(BaseModel):
    model_config = ConfigDict(extra="ignore")

    outbound: list[Route] = []
    inbound: list[Route] = []


def _parse_time(t: str) -> int | None:
    """Parse 'H:MM' or 'HH:MM' time string to minutes."""
    if not t or t == "0:0":
        return None
    try:
        parts = t.split(":")
        return int(parts[0]) * 60 + int(parts[1])
    except (ValueError, IndexError):
        return None
