#pragma once
#include "goap.hpp"
#include "ai.hpp"
#include "config.hpp"
#include <functional>
#include "dinkyecs.hpp"

namespace combat {

  struct BattleEngine {
    std::unordered_map<DinkyECS::Entity, ai::EntityAI&> combatants;

    void add_enemy(DinkyECS::Entity enemy_id, ai::EntityAI& enemy);
    bool plan();
    void fight(std::function<void(DinkyECS::Entity, ai::EntityAI &)> cb);
    void dump();
  };

  struct RitualAI {
    std::string script;
    ai::State start;
    ai::State original;
    ai::State goal;
    ai::ActionPlan plan;

    RitualAI(std::string script, ai::State start, ai::State goal) :
      script(script), start(start), original(start), goal(goal)
    {
    }

    RitualAI() {};

    bool will_do(std::string name);
    void dump();
    ai::Action pop();
  };

  struct RitualEngine {
    Config $config;
    ai::AIProfile $profile;
    std::unordered_map<std::string, ai::Action> $actions;
    std::unordered_map<std::string, ai::State> $states;
    std::unordered_map<std::string, std::vector<ai::Action>> $scripts;

    RitualEngine(std::string config_path);

    ai::State load_state(std::string name);
    ai::Action load_action(std::string name);
    RitualAI start();
    void reset(RitualAI& ritual);
    void set_state(RitualAI& ritual, std::string name, bool setting);
    void plan(RitualAI& ritual);
  };
}