#[cfg(feature = "server")]
use crate::protocol::TbMapEntityId;
use crate::{GameState, physics_layers::GameLayer};
use avian3d::prelude::*;
use bevy::prelude::*;
use bevy_trenchbroom::physics::SceneCollidersReady;
#[cfg(feature = "server")]
use lightyear::prelude::{DisableReplicateHierarchy, NetworkTarget, Replicate};

pub fn plugin(app: &mut App) {
    app.add_systems(OnEnter(GameState::MapLoading), setup_scene);
}

fn setup_scene(mut commands: Commands, asset_server: Res<AssetServer>) {
    commands
        .spawn((
            CollisionLayers::new(LayerMask(GameLayer::Level.to_bits()), LayerMask::ALL),
            SceneRoot(asset_server.load("maps/map1.map#Scene")),
            #[cfg(feature = "server")]
            Replicate::to_clients(NetworkTarget::All),
            #[cfg(feature = "server")]
            DisableReplicateHierarchy,
        ))
        .observe(
            |t: Trigger<SceneCollidersReady>,
             children: Query<&Children>,
             #[cfg(feature = "server")] map_entities: Query<&TbMapEntityId>,
             mut commands: Commands,
             #[cfg(any(feature = "client", feature = "server"))] mut next_game_state: ResMut<
                NextState<GameState>,
            >| {
                info!("map loaded");

                for child in children.get(t.target()).unwrap() {
                    commands.entity(*child).remove::<ChildOf>();

                    #[cfg(feature = "server")]
                    if map_entities.contains(*child) {
                        commands.entity(*child).insert((
                            Replicate::to_clients(NetworkTarget::All),
                            DisableReplicateHierarchy,
                        ));
                    }
                }

                assert!(cfg!(feature = "client") ^ cfg!(feature = "server"));

                #[cfg(feature = "client")]
                next_game_state.set(GameState::Connecting);

                #[cfg(feature = "server")]
                next_game_state.set(GameState::Playing);
            },
        );

    commands.spawn((
        DirectionalLight {
            illuminance: light_consts::lux::OVERCAST_DAY,
            shadows_enabled: true,
            ..default()
        },
        Transform {
            translation: Vec3::new(0.0, 2.0, 0.0),
            rotation: Quat::from_rotation_x(-1.7),
            ..default()
        },
    ));
}
