//! Contextual action buttons for tactical navigation.
//!
//! Provides action buttons based on current state (docked, in-flight, at belt, etc.)

use bevy::prelude::*;

use super::{DockedState, FlightState, SelectedTarget};
use super::scene::PlayerShip;
use super::target::TargetKind;

/// Available action types based on game state.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ActionType {
    Undock,
    Approach,
    Dock,
    StartMining,
    StopMining,
    OpenRefining,
    OpenFitting,
    OpenMarket,
    StartCombat,
}

/// Contextual action that can be shown to the player.
#[derive(Component, Debug, Clone)]
pub struct ContextualAction {
    pub action_type: ActionType,
    pub label: String,
    pub enabled: bool,
    pub tone: ActionTone,
}

/// Visual tone for action buttons.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ActionTone {
    Primary,
    Normal,
    Danger,
}

/// Event fired when an action is triggered.
#[derive(Event, Debug)]
pub struct ActionTriggeredEvent {
    pub action_type: ActionType,
}

/// Plugin for contextual action system.
pub struct ContextualActionPlugin;

impl Plugin for ContextualActionPlugin {
    fn build(&self, app: &mut App) {
        app.add_event::<ActionTriggeredEvent>()
            .add_systems(
                Update,
                (
                    update_contextual_actions,
                    handle_action_buttons,
                ).run_if(in_state(crate::state::AppState::InGame)),
            )
            .add_systems(
                OnEnter(crate::state::AppState::InGame),
                setup_action_ui,
            )
            .add_systems(
                OnExit(crate::state::AppState::InGame),
                despawn_action_ui,
            );
    }
}

/// Marker for action UI entities.
#[derive(Component)]
pub struct ActionUi;

/// Marker for action button entities.
#[derive(Component)]
pub struct ActionButton {
    pub action_type: ActionType,
}

/// Setup action UI panel.
fn setup_action_ui(mut commands: Commands) {
    commands
        .spawn((
            Node {
                position_type: PositionType::Absolute,
                right: Val::Px(20.0),
                bottom: Val::Px(20.0),
                width: Val::Px(250.0),
                flex_direction: FlexDirection::Column,
                row_gap: Val::Px(8.0),
                padding: UiRect::all(Val::Px(12.0)),
                border: UiRect::all(Val::Px(1.0)),
                ..default()
            },
            BackgroundColor(Color::srgba(0.05, 0.07, 0.12, 0.9)),
            BorderColor(Color::srgb(0.25, 0.40, 0.62)),
            BorderRadius::all(Val::Px(8.0)),
            ActionUi,
        ))
        .with_children(|panel| {
            // Title
            panel.spawn((
                Text::new("ACTIONS"),
                TextFont {
                    font_size: 12.0,
                    ..default()
                },
                TextColor(Color::srgb(0.55, 0.65, 0.82)),
            ));

            // Actions will be spawned/updated dynamically
        });
}

/// Update contextual actions based on current state.
fn update_contextual_actions(
    docked_state: Res<DockedState>,
    player_query: Query<(Entity, Option<&SelectedTarget>, Option<&FlightState>), With<PlayerShip>>,
    action_ui_query: Query<(Entity, &Children), With<ActionUi>>,
    mut commands: Commands,
) {
    let Ok((player_entity, selected_target, flight_state)) = player_query.single() else {
        return;
    };

    // Determine available actions based on state
    let actions = get_available_actions(&docked_state, selected_target, flight_state);

    // Update UI
    let Ok((ui_entity, children)) = action_ui_query.single() else {
        return;
    };

    // Clear existing action buttons (keep the title)
    for child in children.iter().skip(1) {
        commands.entity(child).despawn();
    }

    // Spawn new action buttons
    let mut new_actions = actions;
    commands.entity(ui_entity).with_children(|parent| {
        for action in new_actions.drain(..) {
            spawn_action_button(parent, action);
        }
    });
}

/// Get available actions based on current state.
fn get_available_actions(
    docked_state: &DockedState,
    selected_target: Option<&SelectedTarget>,
    flight_state: Option<&FlightState>,
) -> Vec<ContextualAction> {
    let mut actions = Vec::new();

    if docked_state.is_docked {
        // When docked
        actions.push(ContextualAction {
            action_type: ActionType::Undock,
            label: "Undock".to_string(),
            enabled: true,
            tone: ActionTone::Primary,
        });
        actions.push(ContextualAction {
            action_type: ActionType::OpenFitting,
            label: "Fitting".to_string(),
            enabled: true,
            tone: ActionTone::Normal,
        });
        actions.push(ContextualAction {
            action_type: ActionType::OpenMarket,
            label: "Market".to_string(),
            enabled: true,
            tone: ActionTone::Normal,
        });
    } else {
        // When in flight
        if let Some(target) = selected_target {
            match target.kind {
                TargetKind::Station => {
                    actions.push(ContextualAction {
                        action_type: ActionType::Approach,
                        label: format!("Approach {}", target.name),
                        enabled: true,
                        tone: ActionTone::Primary,
                    });
                    actions.push(ContextualAction {
                        action_type: ActionType::Dock,
                        label: "Dock".to_string(),
                        enabled: true,
                        tone: ActionTone::Primary,
                    });
                }
                TargetKind::AsteroidBelt => {
                    actions.push(ContextualAction {
                        action_type: ActionType::Approach,
                        label: format!("Approach {}", target.name),
                        enabled: true,
                        tone: ActionTone::Primary,
                    });
                    actions.push(ContextualAction {
                        action_type: ActionType::StartMining,
                        label: "Start Mining".to_string(),
                        enabled: true,
                        tone: ActionTone::Primary,
                    });
                }
                TargetKind::Hostile => {
                    actions.push(ContextualAction {
                        action_type: ActionType::Approach,
                        label: format!("Engage {}", target.name),
                        enabled: true,
                        tone: ActionTone::Danger,
                    });
                    actions.push(ContextualAction {
                        action_type: ActionType::StartCombat,
                        label: "Start Combat".to_string(),
                        enabled: true,
                        tone: ActionTone::Danger,
                    });
                }
                TargetKind::Manual => {
                    actions.push(ContextualAction {
                        action_type: ActionType::Approach,
                        label: "Approach Waypoint".to_string(),
                        enabled: true,
                        tone: ActionTone::Primary,
                    });
                }
                TargetKind::HabitablePlanet => {
                    actions.push(ContextualAction {
                        action_type: ActionType::Approach,
                        label: format!("Approach {}", target.name),
                        enabled: true,
                        tone: ActionTone::Primary,
                    });
                    actions.push(ContextualAction {
                        action_type: ActionType::Dock,
                        label: "Dock".to_string(),
                        enabled: true,
                        tone: ActionTone::Primary,
                    });
                }
            }
        } else {
            // No target selected
            actions.push(ContextualAction {
                action_type: ActionType::Approach,
                label: "Select a target".to_string(),
                enabled: false,
                tone: ActionTone::Normal,
            });
        }
    }

    actions
}

/// Spawn an action button.
fn spawn_action_button(parent: &mut ChildSpawnerCommands, action: ContextualAction) {
    let (bg_color, border_color) = match action.tone {
        ActionTone::Primary => (
            Color::srgb(0.10, 0.28, 0.22),
            Color::srgb(0.30, 0.72, 0.45),
        ),
        ActionTone::Normal => (
            Color::srgb(0.10, 0.15, 0.20),
            Color::srgb(0.30, 0.40, 0.55),
        ),
        ActionTone::Danger => (
            Color::srgb(0.28, 0.10, 0.10),
            Color::srgb(0.72, 0.30, 0.30),
        ),
    };

    parent
        .spawn((
            Button,
            Node {
                width: Val::Percent(100.0),
                height: Val::Px(36.0),
                justify_content: JustifyContent::Center,
                align_items: AlignItems::Center,
                border: UiRect::all(Val::Px(1.0)),
                ..default()
            },
            BackgroundColor(bg_color),
            BorderColor(border_color),
            BorderRadius::all(Val::Px(4.0)),
            ActionButton {
                action_type: action.action_type,
            },
        ))
        .with_children(|button| {
            button.spawn((
                Text::new(&action.label),
                TextFont {
                    font_size: 14.0,
                    ..default()
                },
                TextColor(if action.enabled {
                    Color::srgb(0.82, 0.90, 1.0)
                } else {
                    Color::srgb(0.40, 0.45, 0.55)
                }),
            ));
        });
}

/// Handle action button clicks.
fn handle_action_buttons(
    mut query: Query<(&Interaction, &ActionButton), Changed<Interaction>>,
    mut events: EventWriter<ActionTriggeredEvent>,
) {
    for (interaction, button) in query.iter_mut() {
        if *interaction == Interaction::Pressed {
            bevy::log::info!("Action triggered: {:?}", button.action_type);
            events.write(ActionTriggeredEvent {
                action_type: button.action_type,
            });
        }
    }
}

/// Despawn action UI.
fn despawn_action_ui(mut commands: Commands, query: Query<Entity, With<ActionUi>>) {
    for entity in query.iter() {
        commands.entity(entity).despawn();
    }
}
