#include <catch2/catch_test_macros.hpp>
#include <iostream>
#include "rituals.hpp"
#include "fsm.hpp"
#include "dinkyecs.hpp"
#include "levelmanager.hpp"

using namespace combat;

TEST_CASE("RitualEngine basic tests", "[rituals]") {
  RitualEngine re("assets/rituals.json");
  auto blanket = re.start();

  re.set_state(blanket, "has_spikes", true);
  re.plan(blanket);

  fmt::println("\n\n------------ TEST WILL DO PIERCE");
  blanket.dump();
  REQUIRE(blanket.will_do("pierce_type"));

  REQUIRE(blanket.start != blanket.original);
  re.reset(blanket);
  REQUIRE(blanket.start == blanket.original);

  re.set_state(blanket, "has_magick", true);
  re.set_state(blanket, "has_spikes", true);
  re.plan(blanket);

  fmt::println("\n\n------------ TEST WILL DO MAGICK TOO");
  blanket.dump();
  REQUIRE(blanket.will_do("pierce_type"));

  blanket.pop();
  REQUIRE(blanket.will_do("magick_type"));

  re.reset(blanket);
  re.set_state(blanket, "has_magick", true);
  re.set_state(blanket, "has_spikes", true);
  re.set_state(blanket, "shiny_bauble", true);
  REQUIRE(blanket.is_combined());
  re.plan(blanket);
  fmt::println("\n\n------------ TEST WILL DO DAMAGE BOOST");
  blanket.dump();

  re.reset(blanket);
  re.set_state(blanket, "has_magick", true);
  re.set_state(blanket, "cursed_item", true);
  re.set_state(blanket, "shiny_bauble", true);
  REQUIRE(blanket.is_combined());
  re.plan(blanket);
  fmt::println("\n\n------------ TEST WILL DO LARGE DAMAGE BOOST");
  blanket.dump();
}

TEST_CASE("blanket can be finalized for the end result", "[rituals]") {
  RitualEngine re("assets/rituals.json");
  auto blanket = re.start();

  re.set_state(blanket, "has_magick", true);
  re.set_state(blanket, "cursed_item", true);
  re.set_state(blanket, "shiny_bauble", true);
  re.plan(blanket);
  REQUIRE(blanket.is_combined());

  fmt::println("\n\n------------ CYCLES AVOIDED");
  blanket.dump();

  auto ritual = re.finalize(blanket);
  ritual.dump();
}


TEST_CASE("the ritual belt works", "[rituals-belt]") {
  RitualBelt the_belt;
  RitualEngine re("assets/rituals.json");
  auto blanket = re.start();

  re.set_state(blanket, "has_magick", true);
  re.plan(blanket);
  REQUIRE(blanket.is_combined());
  blanket.dump();

  {
    auto ritual = re.finalize(blanket);
    the_belt.equip(0, ritual);
    REQUIRE(the_belt.has(0));
  }

  {
    auto ritual = the_belt.get(0);
    ritual.dump();
  }

  {
    the_belt.unequip(0);
    REQUIRE(!the_belt.has(0));
  }
}


TEST_CASE("LevelManager makes a temp belt", "[rituals-belt]") {
  LevelManager lm;
  lm.temp_create_player_rituals();
  auto& level = lm.current();
  auto& the_belt = level.world->get<RitualBelt>(level.player);

  REQUIRE(the_belt.has(0));
  auto& ritual = the_belt.get(0);
  REQUIRE(ritual.damage > 0);

  REQUIRE(the_belt.has(1));
  ritual = the_belt.get(1);
  REQUIRE(ritual.damage > 1);
}