#include "game/components.hpp"
#include "algos/rand.hpp"
#include <algorithm>

namespace components {
  int Combat::attack(Combat &target) {
    int attack = 1;
    int my_dmg = 0;

    my_dmg = Random::uniform<int>(1, damage);
    target.take_damage(my_dmg);

    return my_dmg;
  }

  void Combat::take_damage(int my_dmg) {
    dbc::check(part_names.size() > 2, "Not enough body parts in part_names");

    // select a random body part
    size_t key = Random::uniform(size_t(0), part_names.size() - 1);
    const std::string& name = part_names[key];
    int hp = body_parts[name];

    // catch this bug
    dbc::check(hp >= 0, "HP went negative");

    // don't hit dead parts
    if(hp == 0) return;

    // don't go below 0
    body_parts[name] = std::max(0, hp - my_dmg);
    fmt::println("BODY PART {} was {} now {}", name, hp, body_parts[name]);
  }

  bool Combat::less_than(int level) {
    return body_parts["head"] <= level
      || body_parts["stomach"] <= level
      || body_parts["chest"] <= level;
  }

  bool Combat::is_dead() {
    return less_than(0);
  }

  bool Combat::almost_dead() {
    return less_than(max_hp / 4);
  }

  bool Combat::can_heal() {
    for(auto& [key, hp] : body_parts) {
      if(hp < max_hp) return true;
    }

    return false;
  }

  void Combat::apply_healing(Curative& cure) {
    for(auto& [key, hp] : body_parts) {
      body_parts[key] = std::min(hp + cure.hp, max_hp);
    }
  }
}
