use std::collections::BTreeMap;

use proto::{ItemStoreBin, PlayerStoreNotify, StoreType};

use crate::player::Player;

use super::{AddItemResult, Item};

#[derive(Default)]
pub struct ItemStore {
    pub items: BTreeMap<u64, Item>,
    pub is_material_item_num_alarmed: bool,
}

impl ItemStore {
    pub fn notify_all_data(&self, player: &Player) {
        // TODO: ItemStore::notifyMaxWeight
        self.notify_all_item(player);
    }

    pub fn notify_all_item(&self, player: &Player) {
        player.send_proto(PlayerStoreNotify {
            store_type: StoreType::StorePack.into(),
            weight_limit: 30000,
            item_list: self
                .items
                .iter()
                .map(|(_, item)| item.to_client())
                .collect(),
        })
    }

    pub fn force_add_equip_by_add_avatar(&mut self, item: Item) -> AddItemResult {
        let result = AddItemResult {
            item_id: item.item_id(),
            guid: item.guid(),
            add_count: 1,
            cur_count: 1,
        };

        self.items.insert(item.guid(), item);
        result
    }

    pub fn from_bin(bin: ItemStoreBin) -> Self {
        Self {
            items: bin
                .item_list
                .into_iter()
                .map(|bin| (bin.guid, Item::from_bin(bin)))
                .collect(),
            is_material_item_num_alarmed: bin.is_material_item_num_alarmed,
        }
    }

    pub fn to_bin(&self) -> ItemStoreBin {
        ItemStoreBin {
            item_list: self.items.iter().map(|(_, item)| item.to_bin()).collect(),
            is_material_item_num_alarmed: self.is_material_item_num_alarmed,
            ..Default::default()
        }
    }
}
