//! UI for the docked state within a station.

use bevy::prelude::*;

use crate::gameplay::in_system::{DockedState, UndockEvent};
use crate::gameplay::campaign::CampaignDraft;

const PANEL_BG: Color = Color::srgb(0.05, 0.07, 0.12);
const PANEL_BORDER: Color = Color::srgb(0.25, 0.40, 0.62);
const TEXT_BRIGHT: Color = Color::srgb(0.82, 0.90, 1.0);
const TEXT_DIM: Color = Color::srgb(0.55, 0.65, 0.82);
const BUTTON_BG: Color = Color::srgb(0.10, 0.28, 0.22);
const BUTTON_BORDER: Color = Color::srgb(0.30, 0.72, 0.45);
const BUTTON_HOVER_BG: Color = Color::srgb(0.15, 0.35, 0.28);

const TITLE_FONT_SIZE: f32 = 24.0;
const SUBTITLE_FONT_SIZE: f32 = 14.0;
const BODY_FONT_SIZE: f32 = 14.0;
const BUTTON_FONT_SIZE: f32 = 16.0;

const PANEL_WIDTH: f32 = 360.0;
const SIDE_MARGIN: f32 = 20.0;
const TOP_MARGIN: f32 = 20.0;

/// Marker for UI entities spawned in the docked view.
#[derive(Component)]
pub struct DockedUi;

/// Marker for the station details text.
#[derive(Component)]
pub struct StationDetailsText;

/// Marker for the undock button.
#[derive(Component)]
pub struct UndockButton;

pub fn setup_docked_ui(mut commands: Commands) {
    commands
        .spawn((
            Node {
                width: Val::Percent(100.0),
                height: Val::Percent(100.0),
                position_type: PositionType::Absolute,
                ..default()
            },
            DockedUi,
        ))
        .with_children(|root| {
            spawn_station_panel(root);
        });
}

fn spawn_station_panel(parent: &mut ChildSpawnerCommands) {
    parent
        .spawn((
            Node {
                position_type: PositionType::Absolute,
                left: Val::Px(SIDE_MARGIN),
                top: Val::Px(TOP_MARGIN),
                width: Val::Px(PANEL_WIDTH),
                flex_direction: FlexDirection::Column,
                row_gap: Val::Px(12.0),
                padding: UiRect::all(Val::Px(16.0)),
                border: UiRect::all(Val::Px(1.0)),
                ..default()
            },
            BackgroundColor(PANEL_BG),
            BorderColor(PANEL_BORDER),
            BorderRadius::all(Val::Px(8.0)),
            DockedUi,
        ))
        .with_children(|panel| {
            // Title
            panel.spawn((
                Text::new("Docked"),
                TextFont {
                    font_size: TITLE_FONT_SIZE,
                    ..default()
                },
                TextColor(TEXT_BRIGHT),
            ));

            // Station details placeholder (will be updated by refresh_docked_ui)
            panel.spawn((
                Text::new("Loading station data..."),
                TextFont {
                    font_size: BODY_FONT_SIZE,
                    ..default()
                },
                TextColor(TEXT_DIM),
                StationDetailsText,
            ));

            // Spacer
            panel.spawn(Node {
                flex_grow: 1.0,
                ..default()
            });

            // Undock button
            panel.spawn((
                Button,
                Node {
                    width: Val::Px(160.0),
                    height: Val::Px(44.0),
                    justify_content: JustifyContent::Center,
                    align_items: AlignItems::Center,
                    border: UiRect::all(Val::Px(1.0)),
                    ..default()
                },
                BackgroundColor(BUTTON_BG),
                BorderColor(BUTTON_BORDER),
                BorderRadius::all(Val::Px(6.0)),
                UndockButton,
            ))
            .with_children(|button| {
                button.spawn((
                    Text::new("Undock"),
                    TextFont {
                        font_size: BUTTON_FONT_SIZE,
                        ..default()
                    },
                    TextColor(TEXT_BRIGHT),
                ));
            });
        });
}

pub fn refresh_docked_ui(
    campaign: Res<CampaignDraft>,
    docked_state: Res<DockedState>,
    mut query: Query<&mut Text, With<StationDetailsText>>,
) {
    // Only update when something changed
    if !campaign.is_changed() && !docked_state.is_changed() {
        return;
    }

    let mut text = match query.get_single_mut() {
        Ok(t) => t,
        Err(_) => return,
    };

    let Some(starting_base) = &campaign.starting_base else {
        text.0 = "No station data available.".to_string();
        return;
    };

    let Some(galaxy) = &campaign.galaxy else {
        text.0 = "No galaxy data available.".to_string();
        return;
    };

    // Find the system
    let system_index = match galaxy.systems.iter().position(|s| s.id == starting_base.system_id) {
        Some(idx) => idx,
        None => {
            text.0 = format!("System {} not found.", starting_base.system_id);
            return;
        }
    };

    let system = &galaxy.systems[system_index];
    let contents = &galaxy.contents[system_index];

    // Find the docking station (highest population)
    let station = contents.stations.iter().max_by_key(|s| s.population);

    let station_name = station.map(|s| s.name.as_str()).unwrap_or("Unknown Station");
    let station_pop = station.map(|s| s.population).unwrap_or(0);

    text.0 = format!(
        "{}\n{}\n\nSystem: {} ({})\nFaction: {}\nSecurity: {:.2}\nStation Pop: {}",
        station_name,
        "─".repeat(24),
        system.name,
        system.id,
        system.faction,
        system.security,
        station_pop
    );
}

pub fn undock_button_handler(
    mut commands: Commands,
    mut events: EventWriter<UndockEvent>,
    docked_state: Res<DockedState>,
    query: Query<(&Interaction, &UndockButton), Changed<Interaction>>,
) {
    for (interaction, _) in &query {
        if *interaction == Interaction::Pressed {
            bevy::log::info!("Undock button pressed");

            // Fire the undock event (handled by handle_undock system)
            if let Some(station_entity) = docked_state.station_entity {
                events.send(UndockEvent { station_entity });
            } else {
                bevy::log::warn!("No station entity to undock from");
            }
        }
    }
}

pub fn despawn_docked_ui(mut commands: Commands, query: Query<Entity, With<DockedUi>>) {
    for entity in &query {
        commands.entity(entity).despawn_recursive();
    }
}
