mod camera;
mod gameplay;
mod state;
mod ui;

use bevy::prelude::*;
use bevy::transform::TransformSystem;

use camera::{orbit_camera_control, CameraState, CinematicOverlay, OrbitFocusGoal};
use gameplay::campaign::CampaignDraft;
use gameplay::{
    ai::AiPlugin, character_creation::CharacterCreationPlugin, galaxy::GalaxyPlugin,
    in_system::InSystemPlugin, movement::MovementPlugin, narrative::NarrativePlugin,
    physics::PhysicsPlugin, star_map::StarMapPlugin, starting_base::StartingBasePlugin,
};
use state::AppState;
use ui::main_menu;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .insert_resource(ClearColor(Color::srgb(0.02, 0.02, 0.06)))
        .insert_resource(AmbientLight {
            color: Color::srgb(0.25, 0.3, 0.5),
            brightness: 300.0,
            ..default()
        })
        .init_state::<AppState>()
        .init_resource::<CampaignDraft>()
        .init_resource::<CameraState>()
        .init_resource::<CinematicOverlay>()
        .init_resource::<OrbitFocusGoal>()
        .add_systems(Startup, camera::spawn_camera)
        // Single camera positioning + control system for every 3D scene.
        .add_systems(
            Update,
            orbit_camera_control.run_if(in_camera_scene),
        )
        // Cinematic overlay: toggle + HUD hide. In-game only.
        .add_systems(
            Update,
            (camera::toggle_cinematic, camera::update_cinematic_hud)
                .run_if(in_state(AppState::InGame)),
        )
        // Keep the orbit target locked to the focus entity (ship/station).
        // Runs after transform propagation so the target's GlobalTransform is
        // current.
        .add_systems(
            PostUpdate,
            camera::track_camera_target
                .run_if(in_state(AppState::InGame))
                .after(TransformSystem::TransformPropagate),
        )
        // Drop half-finished focus tweens / a left-on cinematic overlay when
        // leaving a camera-driven scene so they can't bleed into the next one.
        .add_systems(
            OnExit(AppState::InGame),
            camera::reset_transient_camera_state,
        )
        .add_systems(
            OnExit(AppState::StartingBaseSelection),
            camera::reset_transient_camera_state,
        )
        .add_systems(OnEnter(AppState::MainMenu), main_menu::setup_main_menu)
        .add_systems(OnExit(AppState::MainMenu), main_menu::despawn_main_menu)
        .add_systems(Update, main_menu::main_menu_buttons)
        .add_plugins((
            MovementPlugin,
            PhysicsPlugin,
            GalaxyPlugin,
            StarMapPlugin,
            CharacterCreationPlugin,
            StartingBasePlugin,
            InSystemPlugin,
            AiPlugin,
            NarrativePlugin,
        ))
        .run();
}

/// Run condition: true in any 3D scene the camera actively frames.
fn in_camera_scene(state: Res<State<AppState>>) -> bool {
    matches!(
        *state.get(),
        AppState::Galaxy | AppState::StartingBaseSelection | AppState::InGame
    )
}
