#include "rituals.hpp"
#include "battle.hpp"

namespace combat {
  void BattleEngine::add_enemy(Combatant enemy) {
    combatants.try_emplace(enemy.entity, enemy);
  }

  bool BattleEngine::plan() {
    int active = 0;

    for(auto& [entity, enemy] : combatants) {
      enemy.ai.update();
      active += enemy.ai.active();

      if(enemy.ai.active()) {
        if(enemy.ai.wants_to("kill_enemy")) {
          pending_actions.emplace_back(enemy, BattleAction::ATTACK);
        } else if(enemy.ai.wants_to("run_away")) {
          pending_actions.emplace_back(enemy, BattleAction::ESCAPE);
        }
      }
    }

    return active > 0;
  }

  std::optional<BattleResult> BattleEngine::next() {
    if(pending_actions.size() == 0) return std::nullopt;

    auto ba = pending_actions.back();
    pending_actions.pop_back();
    return std::make_optional(ba);
  }

  void BattleEngine::dump() {
    for(auto& [entity, enemy] : combatants) {
      fmt::println("\n\n###### ENTITY #{}", entity);
      enemy.ai.dump();
    }
  }

  void BattleEngine::set(DinkyECS::Entity entity, std::string state, bool setting) {
    dbc::check(combatants.contains(entity), "invalid combatant given to BattleEngine");
    auto& action = combatants.at(entity);
    action.ai.set_state(state, setting);
  }

  void BattleEngine::set_all(std::string state, bool setting) {
    for(auto& [ent, action] : combatants) {
      action.ai.set_state(state, setting);
    }
  }

  void BattleEngine::queue(DinkyECS::Entity entity, BattleAction action) {
    dbc::check(combatants.contains(entity), "invalid combatant given to BattleEngine");
    auto& enemy = combatants.at(entity);
    pending_actions.emplace_back(enemy, action);
  }
}