use bevy_consumable_event::{ConsumableEventReader, ConsumableEvents};
use bevy_ecs::{
    event::Event,
    schedule::{InternedScheduleLabel, IntoSystemConfigs, ScheduleLabel, Schedules, SystemConfigs},
    system::ResMut,
    world::{DeferredWorld, World},
};
#[derive(ScheduleLabel, Debug, PartialEq, Eq, Hash, Clone)]
pub struct AddingSystems;
#[derive(Event)]
pub struct AddSystems(InternedScheduleLabel, SystemConfigs);
impl AddSystems {
                pub fn new<M>(schedule: impl ScheduleLabel, systems: impl IntoSystemConfigs<M>) -> Self {
        let schedule = schedule.intern();
        assert!(!schedule.as_dyn_eq().dyn_eq(&AddingSystems), "Trying to add systems to `AddingSystems` schedule using `AddSystems` event. This is not allowed since `AddSystems` events are consumed during `AddingSystems` schedule.");
        AddSystems(schedule, systems.into_configs())
    }
}
pub fn add_requested_systems(
    mut events: ConsumableEventReader<AddSystems>,
    mut schedules: ResMut<Schedules>,
) {
    for AddSystems(schedule, systems) in events.read_and_consume_all() {
        schedules.add_systems(schedule, systems);
    }
}
pub trait WorldAddSystems {
        fn add_systems<M>(&mut self, schedule: impl ScheduleLabel, systems: impl IntoSystemConfigs<M>);
}
impl WorldAddSystems for DeferredWorld<'_> {
    fn add_systems<M>(&mut self, schedule: impl ScheduleLabel, systems: impl IntoSystemConfigs<M>) {
        self.resource_mut::<ConsumableEvents<AddSystems>>()
            .send(AddSystems::new(schedule, systems));
    }
}
impl WorldAddSystems for World {
    #[inline]
    fn add_systems<M>(&mut self, schedule: impl ScheduleLabel, systems: impl IntoSystemConfigs<M>) {
        Into::<DeferredWorld>::into(self).add_systems(schedule, systems)
    }
}