mod backpack_ui;
mod ui_head_state;

use crate::{
    cash::CashCollectEvent, global_observer, head_drop::HeadCollected, heads::HeadState,
    heads_database::HeadsDatabase,
};
use bevy::prelude::*;

pub use backpack_ui::BackpackAction;
pub use ui_head_state::UiHeadState;

#[derive(Resource, Default)]
pub struct Backpack {
    pub heads: Vec<HeadState>,
}

impl Backpack {
    pub fn reloading(&self) -> bool {
        for head in &self.heads {
            if !head.has_ammo() {
                return true;
            }
        }

        false
    }

    pub fn contains(&self, head_id: usize) -> bool {
        self.heads.iter().any(|head| head.head == head_id)
    }

    pub fn insert(&mut self, head_id: usize, heads_db: &HeadsDatabase) {
        self.heads.push(HeadState::new(head_id, heads_db));
    }
}

#[derive(Event)]
pub struct BackbackSwapEvent(pub usize);

pub fn plugin(app: &mut App) {
    app.init_resource::<Backpack>();

    app.add_plugins(backpack_ui::plugin);

    global_observer!(app, on_head_collect);
}

fn on_head_collect(
    trigger: Trigger<HeadCollected>,
    mut cmds: Commands,
    mut backpack: ResMut<Backpack>,
    heads_db: Res<HeadsDatabase>,
) {
    let HeadCollected(head) = *trigger.event();

    if backpack.contains(head) {
        cmds.trigger(CashCollectEvent);
    } else {
        backpack.insert(head, heads_db.as_ref());
    }
}
