from __future__ import annotations

from point_me.models import (
    Connection,
    Endpoint,
    Fare,
    Payment,
    Route,
    SearchResult,
    Times,
    _parse_time,
)


def test_connection_properties():
    c = Connection(
        departure=Endpoint(airport="JFK"),
        arrival=Endpoint(airport="LHR"),
        airline="BA",
        flight=["BA112"],
        cabin="business",
    )
    assert c.departure_airport == "JFK"
    assert c.arrival_airport == "LHR"
    assert c.flight_number == "BA112"
    assert c.cabin == "business"


def test_connection_extra_fields_ignored():
    c = Connection(
        departure=Endpoint(airport="JFK"),
        arrival=Endpoint(airport="LHR"),
        airline="BA",
        flight=["BA112"],
        cabin="business",
        unknown_future_field="ignored",
    )
    assert c.departure_airport == "JFK"
    assert not hasattr(c, "unknown_future_field")


def test_fare_fields():
    f = Fare(
        program="Avios",
        miles=60000,
        payment=Payment(taxes=200.0, fees=5.0),
    )
    assert f.program_name == "Avios"
    assert f.miles == 60000
    assert f.taxes == 200.0
    assert f.fees == 5.0


def test_fare_defaults():
    f = Fare()
    assert f.miles == 0
    assert f.program == ""
    assert f.taxes == 0.0
    assert f.fees == 0.0


def test_fare_extra_fields_ignored():
    f = Fare(program="Chase UR", miles=50000, unknown="ignored")
    assert not hasattr(f, "unknown")


def test_route_properties():
    r = Route(
        num_stops=1,
        times=Times(flight="8:30", layover="2:00"),
    )
    assert r.stops == 1
    assert r.flight_time_minutes == 510
    assert r.layover_time_minutes == 120


def test_route_default_lists():
    r = Route()
    assert r.connections == []
    assert r.fares == []
    assert r.stops == 0


def test_route_with_nested_models():
    conn = Connection(
        departure=Endpoint(airport="JFK"),
        arrival=Endpoint(airport="LHR"),
        airline="BA",
        flight=["BA112"],
        cabin="business",
    )
    fare = Fare(
        program="Avios",
        miles=60000,
        payment=Payment(taxes=200.0),
    )
    r = Route(num_stops=0, connections=[conn], fares=[fare])
    assert len(r.connections) == 1
    assert r.connections[0].departure_airport == "JFK"
    assert len(r.fares) == 1
    assert r.fares[0].miles == 60000


def test_search_result_empty():
    sr = SearchResult()
    assert sr.routes == []


def test_search_result_with_routes():
    route = Route(num_stops=0)
    sr = SearchResult(routes=[route])
    assert len(sr.routes) == 1
    assert sr.routes[0].stops == 0


def test_parse_time():
    assert _parse_time("6:50") == 410
    assert _parse_time("12:30") == 750
    assert _parse_time("0:0") is None
    assert _parse_time("") is None
    assert _parse_time("invalid") is None


def test_route_none_duration():
    r = Route(times=Times(flight="0:0"))
    assert r.flight_time_minutes is None
