use bevy::prelude::*;
use lightyear::prelude::{Connected, MessageSender};
use shared::{
    GameState, global_observer,
    protocol::{TbMapEntityId, channels::UnorderedReliableChannel, messages::DespawnTbMapEntity},
};

pub fn plugin(app: &mut App) {
    app.register_type::<DespawnedTbEntityCache>();

    app.init_resource::<DespawnedTbEntityCache>();

    app.add_systems(
        OnEnter(GameState::MapLoading),
        |mut cache: ResMut<DespawnedTbEntityCache>| cache.0.clear(),
    );

    global_observer!(app, add_despawned_entities_to_cache);
    global_observer!(app, send_new_client_despawned_cache);
}

fn add_despawned_entities_to_cache(
    trigger: Trigger<OnRemove, TbMapEntityId>,
    id: Query<&TbMapEntityId>,
    mut cache: ResMut<DespawnedTbEntityCache>,
) {
    cache.0.push(id.get(trigger.target()).unwrap().id);
}

#[derive(Default, Resource, Reflect)]
#[reflect(Resource)]
pub struct DespawnedTbEntityCache(pub Vec<u64>);

fn send_new_client_despawned_cache(
    trigger: Trigger<OnAdd, Connected>,
    cache: Res<DespawnedTbEntityCache>,
    mut send: Query<&mut MessageSender<DespawnTbMapEntity>>,
) {
    let mut send = send.get_mut(trigger.target()).unwrap();
    for &id in cache.0.iter() {
        send.send::<UnorderedReliableChannel>(DespawnTbMapEntity(id));
    }
}
