use std::{cell::RefCell, rc::Rc};

use proto::{avatar_bin, AvatarBin};

use crate::{gadget::WeaponGadget, player::item::Weapon};

#[derive(Default)]
pub struct EquipComp {
    pub equip_guid_vec: Vec<u64>,
    pub weapon_gadget: Option<Rc<RefCell<WeaponGadget>>>,
}

impl EquipComp {
    pub fn set_init_weapon(&mut self, weapon_guid: u64) {
        if self.equip_guid_vec.len() != 0 {
            tracing::warn!("weapon has been initialized");
        } else {
            self.equip_guid_vec.push(weapon_guid);
        }
    }

    pub fn init(&mut self, equip_vec: Vec<&Weapon>) {
        let weapon = equip_vec.first().unwrap();

        // TODO: this is old cringe item system, refactor it! (should be: Item->Equip->(Relic, Weapon))
        self.create_and_set_weapon_gadget(weapon.base.base.guid, weapon.base.base.item_id);
    }

    pub fn create_and_set_weapon_gadget(&mut self, weapon_guid: u64, item_id: u32) {
        self.weapon_gadget = Some(Rc::new(RefCell::new(WeaponGadget::new_avatar(
            item_id,
            weapon_guid,
        ))));
    }

    pub fn to_client(&self, info: &mut proto::AvatarInfo) {
        info.equip_guid_list = self.equip_guid_vec.clone();
    }

    pub fn from_bin(bin: &AvatarBin) -> Self {
        if let Some(avatar_bin::Detail::FormalAvatar(avatar)) = bin.detail.as_ref() {
            Self {
                equip_guid_vec: avatar.equip_guid_list.clone(),
                weapon_gadget: None,
            }
        } else {
            Self::default()
        }
    }

    pub fn to_bin(&self, bin: &mut AvatarBin) {
        // Non-formal avatar is not allowed to have persistent equip.
        if let Some(avatar_bin::Detail::FormalAvatar(avatar)) = bin.detail.as_mut() {
            avatar.equip_guid_list = self.equip_guid_vec.clone()
        }
    }
}
