//! In-process level editor library for the Bevy FPS foundation.
#![allow(clippy::type_complexity)]

pub mod assets;
pub mod ext;
pub mod history;
pub mod infra;
pub mod operators;
pub mod play;
pub mod project;
pub mod render_target;
pub mod scene;
pub mod ui;
pub mod viewport;

// Flat re-exports preserve legacy `crate::module` paths.
pub use assets::asset_db;
pub use ext::brp;
pub use ext::command_queue;
pub use ext::extensibility;
#[cfg(feature = "hot-reload")]
pub use ext::hot_reload;
pub use play::net_editor;
pub use play::state;
pub use project::collaboration;
pub use project::diagnostics_bundle;
pub use project::launcher;
pub use project::project_io;
pub use project::session;
pub use project::settings_ui;
pub use scene::scene_io;
pub use scene::scene_schema;
pub use scene::scene_view;
pub use viewport::actor_icons;
pub use viewport::brush_csg;
pub use viewport::brush_edit;
pub use viewport::brush_tool;
pub use viewport::camera;
pub use viewport::gizmos;
pub use viewport::material_drop;
pub use viewport::render_view;
pub use viewport::rendering_diagnostics;
pub use viewport::selection;
pub use viewport::selection_outline;
pub use viewport::visualizers;

use bevy::app::PluginGroupBuilder;
use bevy::prelude::*;
use bevy_egui::EguiPlugin;
use game::{
    launch, GameInputEnabled, GameInputFocused, GamePlugin, GameRenderBootstrap,
    GameSceneBootstrap, SimEnabled,
};
use transform_gizmo_bevy::prelude::TransformGizmoPlugin;

use actor_icons::ActorIconsPlugin;
use asset_db::AssetDbPlugin;
use brush_csg::BrushCsgPlugin;
use brush_edit::BrushEditPlugin;
use brush_tool::BrushToolPlugin;
use camera::EditorCameraPlugin;
use extensibility::ExtensibilityPlugin;
use gizmos::EditorGizmoPlugin;
use history::EditorHistoryPlugin;
use infra::EditorInfraPlugin;
use material_drop::MaterialDropPlugin;
use operators::OperatorPlugin;
use play::audio_preview::AudioPreviewPlugin;
use play::PlaySessionPlugin;
use project::collaboration::CollaborationPlugin;
use project_io::ProjectIoPlugin;
use render_view::RenderViewPlugin;
use scene_io::SceneIoPlugin;
use scene_view::SceneViewPlugin;
use selection::EditorSelectionPlugin;
use selection_outline::SelectionOutlinePlugin;
use session::EditorSessionPlugin;
use settings_ui::SettingsUiPlugin;
use state::EditorStatePlugin;
use ui::EditorUiPlugin;
use viewport::ViewportPlugin;
use visualizers::EditorVisualizersPlugin;

/// Ordered editor plugin bundle. Registration order is part of the startup contract
/// (see `docs/editor/architecture.md` and ADR 0008).
pub struct EditorPluginGroup;

impl PluginGroup for EditorPluginGroup {
    fn build(self) -> PluginGroupBuilder {
        let group = PluginGroupBuilder::start::<Self>()
            .add(EditorInfraPlugin)
            .add(ProjectIoPlugin)
            .add(scene_schema::SceneSchemaPlugin)
            .add(net_editor::NetEditorPlugin)
            .add(AssetDbPlugin)
            .add(OperatorPlugin)
            .add(ExtensibilityPlugin)
            .add(SettingsUiPlugin)
            .add(assets::EditorAssetsPlugin)
            .add(assets::ThumbnailsPlugin)
            .add(EditorStatePlugin)
            .add(RenderViewPlugin)
            .add(SceneViewPlugin)
            .add(PlaySessionPlugin)
            .add(ViewportPlugin)
            .add(BrushCsgPlugin)
            .add(BrushEditPlugin)
            .add(BrushToolPlugin)
            .add(EditorCameraPlugin)
            .add(AudioPreviewPlugin)
            .add(ActorIconsPlugin)
            .add(MaterialDropPlugin)
            .add(EditorSelectionPlugin)
            .add(SelectionOutlinePlugin)
            .add(EditorGizmoPlugin)
            .add(EditorVisualizersPlugin)
            .add(EditorHistoryPlugin)
            .add(SceneIoPlugin)
            .add(CollaborationPlugin)
            .add(EditorUiPlugin)
            .add(EditorSessionPlugin)
            .add(brp::BrpPlugin);
        #[cfg(feature = "hot-reload")]
        let group = group.add(hot_reload::HotReloadPlugin);
        group
    }
}

/// Shared Bevy app wiring for the in-process editor (game sim + egui shell).
pub fn configure_editor_app(app: &mut App) {
    app.add_plugins(launch::default_plugins("Bevy FPS Editor"))
        .insert_resource(GameInputEnabled(false))
        .insert_resource(GameInputFocused(false))
        .insert_resource(SimEnabled(false))
        .insert_resource(GameRenderBootstrap {
            defer_player_camera_fx: true,
        })
        .insert_resource(GameSceneBootstrap {
            defer_default_level: true,
        })
        .add_plugins(GamePlugin)
        .add_plugins(MeshPickingPlugin)
        .add_plugins(TransformGizmoPlugin)
        .add_plugins(EguiPlugin::default())
        .add_plugins(EditorPluginGroup);
}

/// Register game-provided editor panel hooks (ADR 0007 dogfood).
pub fn register_game_editor_plugins(app: &mut App) {
    for setup in game::editor_ext::editor_panel_setups() {
        extensibility::register_editor_plugin(app, Box::new(GamePanelAdapter(*setup)));
    }
    ext::game_inspector::register_game_inspector_sections(app);
}

struct GamePanelAdapter(game::editor_ext::EditorPanelSetup);

impl extensibility::EditorPlugin for GamePanelAdapter {
    fn name(&self) -> &str {
        "game.fps_demo_panel"
    }

    fn register(&self, app: &mut App) {
        (self.0)(app);
        app.add_plugins(ext::game_panels::GameEditorPanelsPlugin);
    }
}
