//! AI state machine definitions.
//!
//! Defines the hierarchical behavior state machine for NPC entities.
//! States include Idle, Patrol, Combat, Flee, Mining, and Trading.

use bevy::prelude::*;

/// The main behavior states for NPC AI.
#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum BehaviorState {
    /// No active behavior - waiting for stimulus
    #[default]
    Idle,
    /// Following a patrol route or pattern
    Patrol,
    /// Engaging in combat with a hostile target
    Combat,
    /// Fleeing from a threat
    Flee,
    /// Mining at an asteroid belt
    Mining,
    /// Trading between stations
    Trading,
}

/// Current AI state component - attached to all NPC entities.
#[derive(Component, Debug, Clone)]
pub struct AiState {
    /// Current behavior state
    pub behavior: BehaviorState,
    /// Time since last state change
    pub time_in_state: f32,
    /// Current target entity (if any)
    pub target_entity: Option<Entity>,
    /// Current target position (if any)
    pub target_position: Option<Vec3>,
    /// Hull percentage (0.0 to 1.0) - affects state transitions
    pub hull_percentage: f32,
}

impl Default for AiState {
    fn default() -> Self {
        Self {
            behavior: BehaviorState::Idle,
            time_in_state: 0.0,
            target_entity: None,
            target_position: None,
            hull_percentage: 1.0,
        }
    }
}

/// State-specific data for patrol behavior.
#[derive(Component, Debug, Clone)]
pub struct PatrolState {
    /// List of waypoints in the patrol route
    pub waypoints: Vec<Vec3>,
    /// Current waypoint index
    pub current_waypoint: usize,
    /// Whether to loop the patrol route
    pub loop_route: bool,
    /// Wait time at each waypoint (seconds)
    pub waypoint_wait_time: f32,
    /// Time spent at current waypoint
    pub time_at_waypoint: f32,
}

impl Default for PatrolState {
    fn default() -> Self {
        Self {
            waypoints: Vec::new(),
            current_waypoint: 0,
            loop_route: true,
            waypoint_wait_time: 2.0,
            time_at_waypoint: 0.0,
        }
    }
}

/// State-specific data for combat behavior.
#[derive(Component, Debug, Clone)]
pub struct CombatState {
    /// Target entity we're fighting
    pub target: Option<Entity>,
    /// Preferred combat distance
    pub preferred_distance: f32,
    /// Time since last attack
    pub time_since_last_attack: f32,
    /// Attack cooldown (seconds)
    pub attack_cooldown: f32,
    /// Whether we're currently attacking
    pub is_attacking: bool,
}

impl Default for CombatState {
    fn default() -> Self {
        Self {
            target: None,
            preferred_distance: 100.0,
            time_since_last_attack: 0.0,
            attack_cooldown: 3.0,
            is_attacking: false,
        }
    }
}

/// State-specific data for flee behavior.
#[derive(Component, Debug, Clone)]
pub struct FleeState {
    /// Entity we're fleeing from
    pub threat: Option<Entity>,
    /// Direction we're fleeing (normalized)
    pub flee_direction: Vec3,
    /// Distance we've fled
    pub distance_fled: f32,
    /// Whether we've reached safe distance
    pub reached_safe_distance: bool,
}

impl Default for FleeState {
    fn default() -> Self {
        Self {
            threat: None,
            flee_direction: Vec3::ZERO,
            distance_fled: 0.0,
            reached_safe_distance: false,
        }
    }
}

/// State-specific data for mining behavior.
#[derive(Component, Debug, Clone)]
pub struct MiningState {
    /// Asteroid belt we're mining at
    pub belt_entity: Option<Entity>,
    /// Time spent mining
    pub mining_time: f32,
    /// Mining cycle duration (seconds)
    pub mining_cycle_duration: f32,
    /// Cargo capacity remaining
    pub cargo_remaining: f32,
}

impl Default for MiningState {
    fn default() -> Self {
        Self {
            belt_entity: None,
            mining_time: 0.0,
            mining_cycle_duration: 8.0,
            cargo_remaining: 100.0,
        }
    }
}

/// State-specific data for trading behavior.
#[derive(Component, Debug, Clone)]
pub struct TradingState {
    /// Current destination station
    pub destination_station: Option<Entity>,
    /// Current trade route waypoints
    pub trade_route: Vec<Vec3>,
    /// Current waypoint in trade route
    pub current_waypoint: usize,
    /// Time until next trade decision
    pub time_until_next_decision: f32,
}

impl Default for TradingState {
    fn default() -> Self {
        Self {
            destination_station: None,
            trade_route: Vec::new(),
            current_waypoint: 0,
            time_until_next_decision: 5.0,
        }
    }
}

/// Event sent when an AI entity transitions to a new state.
#[derive(Event, Debug, Clone)]
pub struct StateTransition {
    /// Entity that changed state
    pub entity: Entity,
    /// Previous state
    pub from_state: BehaviorState,
    /// New state
    pub to_state: BehaviorState,
    /// Reason for transition (for debugging/logging)
    pub reason: String,
}

/// Resource that tracks all AI state machines for debugging and monitoring.
#[derive(Resource, Debug, Default)]
pub struct AiStateMachine {
    /// Count of NPCs in each behavior state
    pub state_counts: [usize; 6],
}

impl AiStateMachine {
    /// Record a state transition for statistics.
    pub fn record_transition(&mut self, from: BehaviorState, to: BehaviorState) {
        // Decrement old state count
        self.state_counts[from as usize] = self.state_counts[from as usize].saturating_sub(1);
        // Increment new state count
        self.state_counts[to as usize] += 1;
    }
}
