from __future__ import annotations

from typing import Dict, Any, TYPE_CHECKING

from .floor import Floor
from .elevator import Elevator

if TYPE_CHECKING:
    from .passenger import Passenger

class Building:
    def __init__(self, n_floors: int, n_elevators: int, elevator_capacity: int = 10) -> None:
        self.elevator_capacity = elevator_capacity
        self.floors = [Floor(f"F__{i}") for i in range(n_floors)]
        self.elevators = [Elevator(elevator_id=f"E__{i}", building=self, capacity=elevator_capacity) for i in range(n_elevators)]

    def __repr__(self) -> str:
        return f"Building(floors={len(self.floors)} floors, elevators={len(self.elevators)} elevators, elevator_capacity={self.elevator_capacity})"

    def to_dict(self) -> Dict[str, Any]:
        return {
            'type': 'Building',
            'elevator_capacity': self.elevator_capacity,
            'floors': {f"F__{i}": floor.to_dict() for i, floor in enumerate(self.floors)},
            'elevators': {f"E__{i}": elevator.to_dict() for i, elevator in enumerate(self.elevators)},
        }

    def tick_movement(self) -> None:
        for elevator in self.elevators:
            elevator.tick_movement()

    def handle_passengers(self, current_tick: int) -> None:
        self.disembark_arrived_passengers(current_tick)
        self.embark_waiting_passengers(current_tick)

    def embark_waiting_passengers(self, current_tick: int) -> None:
        for elevator in self.elevators:
            elevator.embark_waiting_passengers(current_tick)

    def disembark_arrived_passengers(self, current_tick: int) -> None:
        for elevator in self.elevators:
            elevator.disembark_arrived_passengers(current_tick)

    def add_waiting_passenger(self, passenger: Passenger) -> None:
        passenger.origin_floor.add_waiting_passenger(passenger)

    def create_and_add_passenger(self, passenger_id: str, origin_floor_id: str, destination_floor_id: str, tick_appeared: int) -> bool:
        try:
            origin_floor_num = int(origin_floor_id.split('__')[1])
            destination_floor_num = int(destination_floor_id.split('__')[1])

            if origin_floor_num < 0 or origin_floor_num >= len(self.floors):
                print(f"Warning: Origin floor {origin_floor_id} does not exist.")
                return False

            if destination_floor_num < 0 or destination_floor_num >= len(self.floors):
                print(f"Warning: Destination floor {destination_floor_id} does not exist.")
                return False

            origin_floor = self.floors[origin_floor_num]
            destination_floor = self.floors[destination_floor_num]

            origin_floor.create_passenger(passenger_id, destination_floor, tick_appeared)
            return True

        except (ValueError, IndexError) as e:
            print(f"Warning: Could not create passenger {passenger_id}: {e}")
            return False
