use crate::agents::VehicleID;

use std::fmt;

/// Represents the intention type of the agent for the cell
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum IntentionType {
    Undefined,
    /// Indicates whether a cell is wanted to be a target destination
    Target,
    /// Indicates whether a cell is wanted to be a transit cell for vehicles moving with a speed greater than 1
    Transit,
    /// Indicates whether a cell is wanted to be occupied by tail of some vehicle
    Tail,
}

impl fmt::Display for IntentionType {
    /// Formats the intention type for display.
    /// 
    /// Returns a short, lowercase string representation suitable for
    /// logging, debugging, and user interfaces.
    /// 
    /// # Examples
    /// 
    /// ```rust
    /// use micro_traffic_sim_core::intentions::IntentionType;
    ///
    /// assert_eq!(format!("{}", IntentionType::Undefined), "undefined");
    /// assert_eq!(format!("{}", IntentionType::Target), "target");
    /// assert_eq!(format!("{}", IntentionType::Transit), "transit");
    /// assert_eq!(format!("{}", IntentionType::Tail), "tail");
    /// ```
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let intention_str = match self {
            IntentionType::Undefined => "undefined",
            IntentionType::Target => "target",
            IntentionType::Transit => "transit",
            IntentionType::Tail => "tail",
        };
        write!(f, "{}", intention_str)
    }
}

/// Associates a vehicle with its intention type for a cell.
#[derive(Debug, Clone)]
pub struct CellIntention{
    /// ID of the vehicle that has the intention
    pub vehicle_id: VehicleID,
    /// Type of intention for the cell
    pub int_type: IntentionType,
}

impl CellIntention {
    /// Creates a new cell intention with the specified vehicle and intention type.
    ///
    /// # Arguments
    ///
    /// * `vehicle_id` - An ID of the vehicle that has the intention
    /// * `int_type` - The type of intention for the cell (target, transit, or tail)
    ///
    /// # Example
    ///
    /// ```
    /// use micro_traffic_sim_core::agents_types::AgentType;
    /// use micro_traffic_sim_core::agents::Vehicle;
    /// use micro_traffic_sim_core::intentions::{CellIntention, IntentionType};
    ///
    /// let vehicle = Vehicle::new(1)
    ///     .with_type(AgentType::Car)
    ///     .build();
    /// let cell_intention = CellIntention::new(vehicle.id, IntentionType::Target);
    /// println!("Cell intention: {:?}", cell_intention);
    /// ```
    pub fn new(vehicle_id: VehicleID, int_type: IntentionType) -> Self {
        CellIntention { vehicle_id, int_type }
    }

    /// Returns a reference to the associated vehicle if present.
    ///
    /// # Returns
    ///
    /// Returns the vehicle id associated with this intention
    ///
    /// # Example
    ///
    /// ```
    /// use micro_traffic_sim_core::agents_types::AgentType;
    /// use micro_traffic_sim_core::agents::Vehicle;
    /// use micro_traffic_sim_core::intentions::{CellIntention, IntentionType};
    ///
    /// let vehicle = Vehicle::new(1)
    ///     .with_type(AgentType::Car)
    ///     .build();
    /// let cell_intention = CellIntention::new(vehicle.id, IntentionType::Target);
    /// println!("Cell intention: {:?}", cell_intention);
    /// println!("Associated vehicle ID: {}", cell_intention.get_vehicle_id());
    /// ```
    pub fn get_vehicle_id(&self) -> u64 {
        self.vehicle_id
    }
}
