from elevator_traffic_analysis.floor import Floor
from elevator_traffic_analysis.passenger import Passenger


def test_floor_creation():
    """
    Given: A floor ID is provided
    When: A Floor object is created
    Then: The floor has correct properties and empty passenger lists
    """
    floor = Floor(floor_id="floor__1")
    assert floor.floor_id == "floor__1"
    assert len(floor.waiting_passengers) == 0
    assert len(floor.dismbarked_passengers) == 0
    assert int(floor) == 1


def test_passenger_creation():
    """
    Given: Origin and destination floors exist
    When: A passenger is created via floor's create_passenger method
    Then: The passenger is initialized correctly and added to waiting passengers
    """
    origin_floor = Floor(floor_id="floor__0")
    destination_floor = Floor(floor_id="floor__5")

    passenger = origin_floor.create_passenger(
        passenger_id="passenger_1",
        destination_floor=destination_floor,
        tick_appeared=10
    )

    assert passenger.passenger_id == "passenger_1"
    assert passenger.origin_floor == origin_floor
    assert passenger.destination_floor == destination_floor
    assert passenger.tick_appeared == 10
    assert passenger.state == "WAITING"
    assert len(origin_floor.waiting_passengers) == 1


def test_passenger_state_transitions():
    """
    Given: A passenger in WAITING state
    When: The passenger embarks and then disembarks
    Then: The passenger state transitions correctly through all stages
    """
    origin_floor = Floor(floor_id="floor__0")
    destination_floor = Floor(floor_id="floor__5")

    passenger = Passenger(
        passenger_id="passenger_1",
        origin_floor=origin_floor,
        destination_floor=destination_floor,
        tick_appeared=10
    )

    assert passenger.state == "WAITING"

    passenger.embark(tick=15)
    assert passenger.state == "EMBARKED"
    assert passenger.tick_embarked == 15

    passenger.disembark(tick=25)
    assert passenger.state == "DISEMBARKED"
    assert passenger.tick_disembarked == 25


def test_passenger_stats():
    """
    Given: A passenger that has completed their journey
    When: get_stats is called
    Then: Wait, ride, and serve time statistics are correctly calculated
    """
    origin_floor = Floor(floor_id="floor__0")
    destination_floor = Floor(floor_id="floor__5")

    passenger = Passenger(
        passenger_id="passenger_1",
        origin_floor=origin_floor,
        destination_floor=destination_floor,
        tick_appeared=10
    )

    # Stats should be None before disembarking
    assert passenger.get_stats() is None

    passenger.embark(tick=15)
    assert passenger.get_stats() is None

    passenger.disembark(tick=25)
    stats = passenger.get_stats()

    assert stats is not None
    assert stats["tick_appeared"] == 10
    assert stats["tick_embarked"] == 15
    assert stats["tick_disembarked"] == 25
    assert stats["n_wait_ticks"] == 5  # 15 - 10
    assert stats["n_ride_ticks"] == 10  # 25 - 15
    assert stats["n_serve_ticks"] == 15  # 25 - 10
