#include <catch2/catch_test_macros.hpp>
#include <fmt/core.h>
#include <nlohmann/json.hpp>
#include <fstream>
#include "algos/pathing.hpp"
#include "algos/matrix.hpp"
#include "ai/ai.hpp"
#include "game/level.hpp"
#include <chrono>
#include <thread>
#include "algos/rand.hpp"
#include "game/systems.hpp"
#include "constants.hpp"

using namespace fmt;
using namespace nlohmann;
using std::string;
using namespace components;
using namespace std::chrono_literals;

json load_test_pathing(const string &fname) {
  std::ifstream infile(fname);
  return json::parse(infile);
}

TEST_CASE("multiple targets can path", "[pathing]") {
  GameDB::init();
  auto level = GameDB::create_level();
  auto walls_copy = level.map->$walls;
  Pathing paths{matrix::width(walls_copy), matrix::height(walls_copy)};

  System::multi_path<Combat>(level, paths, walls_copy);

  bool diag = Random::uniform<int>(0, 1);
  auto pos = GameDB::player_position().location;
  auto found = paths.find_path(pos, PATHING_TOWARD, diag);

  while(found == PathingResult::CONTINUE) {
    // fmt::println("\033[2J\033[1;1H");
    // matrix::dump(diag ? "diag" : "simple", paths.$paths, pos.x, pos.y);
    // std::this_thread::sleep_for(200ms);
    found = paths.find_path(pos, PATHING_TOWARD, diag);
  }

  // fmt::println("\033[2J\033[1;1H");
  // matrix::dump(diag ? "diag" : "simple", paths.$paths, pos.x, pos.y);

  if(found == PathingResult::FOUND) {
    fmt::println("FOUND!");
  } else if(found == PathingResult::FAIL && !diag) {
    REQUIRE(found != PathingResult::FAIL);
  }
}
