use anyhow::Result;

use crate::equipment::{
    comp::Comp, gun::Gun, hat::Hat, pants::Pants, shirt::Shirt, shoes::Shoes, sword::Sword,
};

#[derive(Debug, Clone)]
pub struct BagEquipment {
    swords: Option<Vec<Sword>>,
    guns: Option<Vec<Gun>>,
    comps: Option<Vec<Comp>>,
    hats: Option<Vec<Hat>>,
    shirts: Option<Vec<Shirt>>,
    pants: Option<Vec<Pants>>,
    shoes: Option<Vec<Shoes>>,
}
impl BagEquipment {
    pub fn new() -> Self {
        Self {
            swords: None,
            guns: None,
            comps: None,
            hats: None,
            shirts: None,
            pants: None,
            shoes: None,
        }
    }
    pub fn swords(&self) -> Option<Vec<Sword>> {
        self.swords.clone()
    }
    pub fn guns(&self) -> Option<Vec<Gun>> {
        self.guns.clone()
    }
    pub fn comps(&self) -> Option<Vec<Comp>> {
        self.comps.clone()
    }
    pub fn hats(&self) -> Option<Vec<Hat>> {
        self.hats.clone()
    }
    pub fn shirts(&self) -> Option<Vec<Shirt>> {
        self.shirts.clone()
    }
    pub fn pants(&self) -> Option<Vec<Pants>> {
        self.pants.clone()
    }
    pub fn shoes(&self) -> Option<Vec<Shoes>> {
        self.shoes.clone()
    }
    pub fn add_sword(&mut self, sword: Sword) -> Result<()> {
        let mut swords = match self.clone().swords {
            Some(s) => s,
            None => Vec::new(),
        };
        swords.push(sword);
        self.swords = Some(swords);
        Ok(())
    }
    pub fn add_gun(&mut self, gun: Gun) -> Result<()> {
        let mut guns = match self.clone().guns {
            Some(g) => g,
            None => Vec::new(),
        };
        guns.push(gun);
        self.guns = Some(guns);
        Ok(())
    }
    pub fn add_comp(&mut self, comp: Comp) -> Result<()> {
        let mut comps = match self.clone().comps {
            Some(c) => c,
            None => Vec::new(),
        };
        comps.push(comp);
        self.comps = Some(comps);
        Ok(())
    }
    pub fn add_hat(&mut self, hat: Hat) -> Result<()> {
        let mut hats = match self.clone().hats {
            Some(h) => h,
            None => Vec::new(),
        };
        hats.push(hat);
        self.hats = Some(hats);
        Ok(())
    }
    pub fn add_shirt(&mut self, shirt: Shirt) -> Result<()> {
        let mut shirts = match self.clone().shirts {
            Some(s) => s,
            None => Vec::new(),
        };
        shirts.push(shirt);
        self.shirts = Some(shirts);
        Ok(())
    }
    pub fn add_pant(&mut self, pant: Pants) -> Result<()> {
        let mut pants = match self.clone().pants {
            Some(p) => p,
            None => Vec::new(),
        };
        pants.push(pant);
        self.pants = Some(pants);
        Ok(())
    }
    pub fn add_shoe(&mut self, shoe: Shoes) -> Result<()> {
        let mut shoes = match self.clone().shoes {
            Some(s) => s,
            None => Vec::new(),
        };
        shoes.push(shoe);
        self.shoes = Some(shoes);
        Ok(())
    }
    pub fn set_swords(&mut self, swords: Option<Vec<Sword>>) -> Result<()> {
        self.swords = swords;
        Ok(())
    }
    pub fn set_guns(&mut self, guns: Option<Vec<Gun>>) -> Result<()> {
        self.guns = guns;
        Ok(())
    }
    pub fn set_comps(&mut self, comps: Option<Vec<Comp>>) -> Result<()> {
        self.comps = comps;
        Ok(())
    }
    pub fn set_hats(&mut self, hats: Option<Vec<Hat>>) -> Result<()> {
        self.hats = hats;
        Ok(())
    }
    pub fn set_shirts(&mut self, shirts: Option<Vec<Shirt>>) -> Result<()> {
        self.shirts = shirts;
        Ok(())
    }
    pub fn set_pants(&mut self, pants: Option<Vec<Pants>>) -> Result<()> {
        self.pants = pants;
        Ok(())
    }
    pub fn set_shoes(&mut self, shoes: Option<Vec<Shoes>>) -> Result<()> {
        self.shoes = shoes;
        Ok(())
    }
}

pub struct Inventory {
    equipment: Option<BagEquipment>,
}
impl Inventory {
    pub fn new() -> Self {
        Self {
            equipment: None,
        }
    }
    pub fn set_equipment(&mut self, equipment: Option<BagEquipment>) -> Result<()> {
        self.equipment = equipment;
        Ok(())
    }
}