#include "inventory.hpp"
#include <fmt/core.h>


namespace components {
  void Inventory::add(InventoryItem new_item) {
    for(auto &slot : items) {
      if(new_item.data["id"] == slot.data["id"]) {
        slot.count += new_item.count;
        return;
      }
    }

    items.push_back(new_item);
  }

  bool Inventory::has_item(size_t at) {
    fmt::println(">>> INVENTORY: requesting item at {}, have {} items in stock", at, items.size());
    return at < items.size();
  }

  InventoryItem& Inventory::get(size_t at) {
    dbc::check(at < items.size(), fmt::format("inventory index {} too big", at));
    return items[at];
  }

  bool Inventory::decrease(size_t at, int count) {
    dbc::check(at < items.size(), fmt::format("inventory index {} too big", at));
    auto &slot = items[at];
    slot.count -= count;
    return slot.count > 0;
  }

  void Inventory::erase_item(size_t at) {
    dbc::check(at < items.size(), fmt::format("inventory index {} too big", at));
    items.erase(items.begin() + at);
  }

  int Inventory::item_index(std::string id) {
    for(size_t i = 0; i < items.size(); i++) {
      if(items[i].data["id"] == id) {
        return i;
      }
    }

    return -1;
  }

  std::pair<bool, std::string> Inventory::use(GameLevel &level, size_t at) {
    auto& player_combat = level.world->get<components::Combat>(level.player);
    auto& item = get(at);

    if(item.count == 0) return {false, item.data["name"]};

    if(item.data["id"] == "SWORD_RUSTY") {
      auto weapon = components::get<components::Weapon>(item.data);
      player_combat.damage = weapon.damage;
    } else if(item.data["id"] == "POTION_HEALING_SMALL") {
      auto cure = components::get<components::Curative>(item.data);
      player_combat.hp = std::min(player_combat.hp + cure.hp, player_combat.max_hp);
    } else if(item.data["id"] == "TORCH_BAD") {
      auto new_light = components::get<components::LightSource>(item.data);
      level.world->set<components::LightSource>(level.player, new_light);
      light = new_light;
    } else {
      return {false, fmt::format("UNKNOWN ITEM: {}", (std::string)item.data["id"])};
    }

    decrease(at, 1);
    return {true, item.data["name"]};
  }



}