from __future__ import annotations

from typing import TYPE_CHECKING, Any, Dict, Optional

from transitions import Machine

if TYPE_CHECKING:
    from .floor import Floor

class Passenger:
    states = ["WAITING", "EMBARKED", "DISEMBARKED"]

    def __init__(self, passenger_id: str, origin_floor: Floor, destination_floor: Floor, tick_appeared: int) -> None:
        self.passenger_id: str = passenger_id
        self.origin_floor: Floor = origin_floor
        self.destination_floor: Floor = destination_floor

        self.machine = Machine(model=self, states=Passenger.states, initial="WAITING")
        self.machine.add_transition("_embark", "WAITING", "EMBARKED")
        self.machine.add_transition("_disembark", "EMBARKED", "DISEMBARKED")

        self.tick_appeared: int = tick_appeared
        self.tick_embarked: Optional[int] = None
        self.tick_disembarked: Optional[int] = None

    def embark(self, tick: int) -> None:
        self._embark()
        self.tick_embarked = tick

    def disembark(self, tick: int) -> None:
        self._disembark()
        self.tick_disembarked = tick

    def __repr__(self) -> str:
        return f"Passenger(id={self.passenger_id}, origin={self.origin_floor.floor_id}, destination={self.destination_floor.floor_id}, state={self.state})"

    def to_dict(self) -> Dict[str, Any]:
        """Returns a dictionary representation for pretty printing"""
        return {
            'type': 'Passenger',
            'id': self.passenger_id,
            'origin_floor_id': self.origin_floor.floor_id,
            'destination_floor_id': self.destination_floor.floor_id,
            'state': self.state,
            'tick_appeared': self.tick_appeared,
            'tick_embarked': self.tick_embarked,
            'tick_disembarked': self.tick_disembarked,
            'stats': self.get_stats()
        }


    def get_stats(self) -> Optional[Dict[str, int]]:
        if self.state != "DISEMBARKED":
            return None
        return {
            "tick_appeared": self.tick_appeared,
            "tick_embarked": self.tick_embarked,
            "tick_disembarked": self.tick_disembarked,
            "n_serve_ticks": self.tick_disembarked - self.tick_appeared,
            "n_ride_ticks": self.tick_disembarked - self.tick_embarked,
            "n_wait_ticks": self.tick_embarked - self.tick_appeared
        }
