//! Target selection system for tactical navigation.
//!
//! Handles selecting and tracking targets (stations, asteroid belts, hostiles)
//! for point-and-click navigation.

use bevy::prelude::*;
use bevy::window::PrimaryWindow;
use super::scene::PlayerShip;

/// The kind of target being selected.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TargetKind {
    Station,
    AsteroidBelt,
    Hostile,
    Manual,
    HabitablePlanet,
}

/// Selected target component. Can be attached to the player ship
/// to track what target the player has selected.
#[derive(Component, Debug, Clone)]
pub struct SelectedTarget {
    pub entity: Entity,
    pub kind: TargetKind,
    pub name: String,
}

/// Targetable component. Entities that can be selected as navigation targets
/// should have this component.
#[derive(Component, Debug, Clone)]
pub struct Targetable {
    pub kind: TargetKind,
    pub name: String,
}

/// Event fired when a target is selected.
#[derive(Event, Debug)]
pub struct TargetSelectedEvent {
    pub entity: Entity,
    pub kind: TargetKind,
    pub name: String,
}

/// Plugin for target selection system.
pub struct TargetSelectionPlugin;

impl Plugin for TargetSelectionPlugin {
    fn build(&self, app: &mut App) {
        app.add_event::<TargetSelectedEvent>()
            .add_systems(
                Update,
                handle_target_selection.run_if(in_state(crate::state::AppState::InGame)),
            );
    }
}

/// Handle target selection via click events.
fn handle_target_selection(
    mouse_input: Res<ButtonInput<MouseButton>>,
    primary_window: Query<&Window, With<PrimaryWindow>>,
    camera_query: Query<(&Camera, &GlobalTransform), With<crate::camera::MainCamera>>,
    targetable_query: Query<(Entity, &Targetable, &GlobalTransform)>,
    mut events: EventWriter<TargetSelectedEvent>,
    mut player_query: Query<&mut SelectedTarget, With<PlayerShip>>,
) {
    // Only handle left clicks
    if !mouse_input.just_pressed(MouseButton::Left) {
        return;
    }

    let Ok(window) = primary_window.single() else {
        return;
    };

    let Some(cursor_pos) = window.cursor_position() else {
        return;
    };

    let Ok((camera, camera_gt)) = camera_query.single() else {
        return;
    };

    // Check for clicks on targetable entities using raycasting
    let mut closest_target: Option<(Entity, TargetKind, String, f32)> = None;
    let mut closest_distance = f32::MAX;

    for (entity, targetable, global_transform) in targetable_query.iter() {
        let target_pos = global_transform.translation();
        let distance = camera_gt.translation().distance(target_pos);

        // Simple distance-based selection for now
        // In a full implementation, you'd use proper raycasting with bounding volumes
        if distance < closest_distance && distance < 100.0 {
            // Within 100 units
            closest_distance = distance;
            closest_target = Some((entity, targetable.kind, targetable.name.clone(), distance));
        }
    }

    // If we found a target, select it
    if let Some((entity, kind, name, _distance)) = closest_target {
        bevy::log::info!("Selected target: {} ({:?})", name, kind);

        // Update player's selected target
        if let Ok(mut selected) = player_query.single_mut() {
            selected.entity = entity;
            selected.kind = kind;
            selected.name = name.clone();
        }

        // Fire event
        events.write(TargetSelectedEvent {
            entity,
            kind,
            name,
        });
    }
}
