#pragma once
#include "goap.hpp"
#include "ai.hpp"
#include "config.hpp"
#include "dinkyecs.hpp"
#include "components.hpp"

namespace combat {
  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();
    bool is_combined();
  };

  enum class RitualElement {
    NONE=0, FIRE=1, LIGHTNING=2
  };

  enum class RitualKind {
    NONE=0, PHYSICAL=1, MAGICK=2
  };

  struct RitualAction {
    float probability = 1.0f;
    int damage = 0;
    RitualKind kind{RitualKind::NONE};
    RitualElement element{RitualElement::NONE};
    std::vector<std::string> names;

    void dump();
  };

  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);
    RitualAction finalize(RitualAI& ritual);
  };

  struct RitualBelt {
    std::unordered_map<int, RitualAction> equipped;

    RitualAction& get(int index);
    void equip(int index, RitualAction& action);
    bool has(int index);
    void unequip(int index);
  };
}