use bevy::{
    diagnostic::FrameTimeDiagnosticsPlugin,
    prelude::{App, IntoSystemDescriptor, Plugin, ReflectResource, Resource},
    reflect::Reflect,
};
use bevy_rapier3d::prelude::{NoUserData, RapierPhysicsPlugin};

mod components;
mod systems;

pub use components::*;
use systems::*;

#[derive(Resource, Default, Debug, Reflect)]
#[reflect(Resource)]
struct CyberLean {
    pub lean: f32,
}

pub struct CyberActionPlugin;
impl Plugin for CyberActionPlugin {
    fn build(&self, app: &mut App) {
        app.init_resource::<MovementSettings>()
            .register_type::<MovementSettings>()
            .init_resource::<CatControllerSettings>()
            .init_resource::<ActionDebugInstant>()
            .init_resource::<CyberLean>()
            .register_type::<CyberLean>()
            .register_type::<CatControllerSettings>()
            .add_plugin(RapierPhysicsPlugin::<NoUserData>::default())
            .add_plugin(FrameTimeDiagnosticsPlugin::default())
            .add_system(surface_fix.label("surface_fix"))
            .add_system(gravity.label("gravity").before("cat"))
            .add_system(cyber_lean.before("cat").after("gravity"))
            .add_system(falling_cat.label("cat"))
            .add_system(input_forces.label("iforces").after("cat"))
            .add_system(
                tunnel_out
                    .label("tunnel")
                    .before("surface_fix")
                    .after("drag"),
            )
            .add_system(surface_fix.label("surface_fix").after("cat"))
            .add_system(drag.label("drag").after("iforces"));
    }
}
