#include <catch2/catch_test_macros.hpp>
#include "components.hpp"
#include "dinkyecs.hpp"
#include "config.hpp"
#include <iostream>
#include "easings.hpp"

using namespace components;
using namespace DinkyECS;

TEST_CASE("confirm component loading works", "[components]") {
  std::vector<std::string> test_list{
    "assets/enemies.json", "assets/items.json", "assets/devices.json"};

  components::ComponentMap comp_map;
  components::configure(comp_map);
  DinkyECS::World world;

  for(auto test_data : test_list) {
    Config config(test_data);
    auto data_list = config.json();

    for(auto& [key, data] : data_list.items()) {
      auto& components = data["components"];
      fmt::println("TEST COMPONENT: {} from file {}", key, test_data);
      auto ent = world.entity();
      components::configure_entity(comp_map, world, ent, components);
    }
  }
}

TEST_CASE("make sure json_mods works", "[components]") {
  Config config("assets/bosses.json");
  // this confirms that loading something with an optional
  // field works with the json conversions in json_mods.hpp
  for(auto& comp_data : config["RAT_KING"]["components"]) {
    if(comp_data["_type"] == "BossFight") {
      auto comp = components::convert<components::BossFight>(comp_data);
      // the boss fight for the rat king doesn't have a stage so false=optional
      REQUIRE(comp.stage == std::nullopt);
    }
  }

  // this then confirms everything else about the json conversion

  ComponentMap comp_map;
  components::configure(comp_map);

  DinkyECS::World world;
  auto rat_king = world.entity();

  components::configure_entity(comp_map, world, rat_king, config["RAT_KING"]["components"]);

  auto boss = world.get<BossFight>(rat_king);
  REQUIRE(boss.stage == std::nullopt);

  // now load the other one for the other way optional is used
  auto devils_fingers = world.entity();
  components::configure_entity(comp_map, world, devils_fingers, config["DEVILS_FINGERS"]["components"]);
  auto boss2 = world.get<BossFight>(devils_fingers);
  REQUIRE(boss2.stage != std::nullopt);
}