use avian3d::prelude::PhysicsDebugPlugin;
use avian3d::PhysicsPlugins;
use bevy::core_pipeline::CorePipelinePlugin;
use bevy::gizmos::GizmoPlugin;
use bevy::log::LogPlugin;
use bevy::pbr::PbrPlugin;
use bevy::prelude::*;
use bevy::render::RenderPlugin;
use bevy::sprite::SpritePlugin;
use bevy::state::app::StatesPlugin;
use bevy::text::TextPlugin;
use bevy::winit::WinitPlugin;
use bevy_editor_pls::prelude::*;
use blenvy::BlenvyPlugin;
use char_controller::CharacterControllerPlugin;
use clap::Parser;
use client::MyClientPlugin;
use lightyear::prelude::client::ClientPlugins;
use lightyear::prelude::server::ServerPlugins;
use server::MyServerPlugin;
use setup::{Player, PlayerHead, SetupPlugin};

pub mod char_controller;
pub mod client;
pub mod protocol;
pub mod server;
pub mod setup;
pub mod shared_net;

lazy_static::lazy_static! {
    pub static ref CONFIG: Cli = {
        Cli::parse()
    };
}

pub struct ClientOrServerPlugin;
impl Plugin for ClientOrServerPlugin {
    fn build(&self, app: &mut App) {
        if CONFIG.client {
            app.add_plugins(DefaultPlugins)
                .add_plugins(ClientPlugins::new(shared_net::client_config()))
                .add_plugins(EditorPlugin::default())
                .add_plugins(MyClientPlugin);
        }
        if CONFIG.server {
            app.add_plugins(
                DefaultPlugins.build(), // .disable::<RenderPlugin>()
                                        // .disable::<PbrPlugin>()
                                        // .disable::<CorePipelinePlugin>()
                                        // .disable::<ImagePlugin>()
                                        // .disable::<TextPlugin>()
                                        // .disable::<SpritePlugin>()
                                        // .disable::<WindowPlugin>()
                                        // .disable::<WinitPlugin>()
                                        // .disable::<GizmoPlugin>(),
            )
            .add_plugins(ServerPlugins::new(shared_net::server_config()))
            .add_plugins(MyServerPlugin);
        }
    }
}

#[derive(Parser)]
#[command(version, about, long_about = None)]
pub struct Cli {
    /// Start as a client.
    #[arg(short, long)]
    client: bool,
    /// Start as a server.
    #[arg(short, long)]
    server: bool,
}
fn main() {
    App::new()
        .insert_resource(Msaa::Sample4)
        .insert_resource(AmbientLight {
            brightness: 200.0,
            ..default()
        })
        .add_plugins(ClientOrServerPlugin)
        .add_plugins(SetupPlugin)
        .add_plugins((
            PhysicsPlugins::default(),
            PhysicsDebugPlugin::default(),
            CharacterControllerPlugin,
        ))
        .add_plugins(protocol::ProtocolPlugin)
        .add_plugins(BlenvyPlugin::default())
        .run();
}
