//! In-system HUD orchestration: the panel swap between the station (docked)
//! info panel and the flight HUD.
//!
//! Inside a system the player is always in exactly one mode —
//! [`Docked`](super::scene::Docked) at a station, or in active
//! [`FlightState`](super::FlightState). This module keeps the on-screen HUD in
//! sync with that state: the station info panel ([`super::ui`]) is shown while
//! docked, the flight HUD ([`super::flight_ui`]) while flying. The contextual
//! action panel ([`super::actions`]) is always present and adapts its buttons
//! to the current mode.
//!
//! The swap is **reactive and idempotent**: a single [`Update`] system compares
//! the player's mode against the panels currently on screen and only
//! spawns/despawns when they disagree. This is more robust than scattering
//! spawn/despawn calls through the undock/dock transition systems, because any
//! code path that flips the player's `Docked`/`FlightState` components is
//! automatically reflected in the UI a frame later.
//!
//! Both panels are spawned as small, corner-anchored overlays with no
//! full-screen root, so they never block camera orbit input except when the
//! cursor is directly over a panel (see `cursor_over_ui` in `camera.rs`).

use bevy::prelude::*;

use super::scene::{Docked, PlayerShip};
use super::{FlightState, flight_ui, ui};

/// Keep the on-screen HUD matched to the player's docking/flight mode.
///
/// - Docked → the station info panel ([`ui::DockedUi`]) is shown.
/// - Flying → the flight HUD ([`flight_ui::FlightUi`]) is shown.
///
/// Cheap to run every frame: it only mutates the world when the on-screen
/// panel disagrees with the player's state.
pub fn sync_hud_panels(
    mut commands: Commands,
    docked_player: Query<&Docked, With<PlayerShip>>,
    flying_player: Query<&FlightState, With<PlayerShip>>,
    docked_panels: Query<Entity, With<ui::DockedUi>>,
    flight_panels: Query<Entity, With<flight_ui::FlightUi>>,
) {
    let is_docked = docked_player.single().is_ok();
    let is_flying = flying_player.single().is_ok();

    // Station info panel ↔ docked mode.
    if is_docked {
        if docked_panels.is_empty() {
            ui::setup_docked_ui(commands.reborrow());
        }
    } else {
        for entity in &docked_panels {
            commands.entity(entity).despawn();
        }
    }

    // Flight HUD ↔ flight mode.
    if is_flying {
        if flight_panels.is_empty() {
            flight_ui::setup_flight_ui(commands.reborrow());
        }
    } else {
        for entity in &flight_panels {
            commands.entity(entity).despawn();
        }
    }
}

/// Tear down every in-system HUD panel when leaving the scene.
///
/// The reactive [`sync_hud_panels`] system stops running once we leave
/// [`AppState::InGame`](crate::state::AppState::InGame), so any panel still on
/// screen is removed explicitly here.
pub fn despawn_in_system_hud(
    mut commands: Commands,
    docked_panels: Query<Entity, With<ui::DockedUi>>,
    flight_panels: Query<Entity, With<flight_ui::FlightUi>>,
) {
    for entity in &docked_panels {
        commands.entity(entity).despawn();
    }
    for entity in &flight_panels {
        commands.entity(entity).despawn();
    }
}
