#ifdef TESTS_BUILD
#include <CreatureLib/Battling/TurnChoices/AttackTurnChoice.hpp>
#include <CreatureLib/Battling/TurnChoices/PassTurnChoice.hpp>
#include "../../extern/doctest.hpp"
#include "../../src/Battling/Battle/Battle.hpp"
#include "../../src/Battling/Pokemon/CreatePokemon.hpp"
#include "../../src/Battling/Pokemon/PokemonParty.hpp"
#include "../TestLibrary/TestLibrary.hpp"

TEST_CASE("Create and delete Pokemon") {
    auto lib = TestLibrary::GetLibrary();
    auto mon = PkmnLib::Battling::CreatePokemon(lib, "testSpecies"_cnc, 1).Build();
    delete mon;
}

TEST_CASE("Get Nature from Pokemon") {
    auto lib = TestLibrary::GetLibrary();
    auto mon = PkmnLib::Battling::CreatePokemon(lib, "testSpecies"_cnc, 1).WithNature("neutralNature"_cnc).Build();
    auto nature = mon->GetNature();
    REQUIRE(nature->GetDecreaseModifier() == 1);
    REQUIRE(nature->GetIncreaseModifier() == 1);
    delete mon;
}

TEST_CASE("Get Attack name from Pokemon") {
    auto lib = TestLibrary::GetLibrary();
    auto mon = PkmnLib::Battling::CreatePokemon(lib, "testSpecies"_cnc, 1)
                   .LearnMove("testMove"_cnc, CreatureLib::Battling::AttackLearnMethod::Level)
                   .LearnMove("testMove2"_cnc, CreatureLib::Battling::AttackLearnMethod::Level)
                   .Build();
    auto move = mon->GetMoves()[0].GetValue();
    REQUIRE(move->GetMoveData()->GetName() == "testMove"_cnc);
    auto move2 = mon->GetMoves()[1].GetValue();
    REQUIRE(move2->GetMoveData()->GetName() == "testMove2"_cnc);
    delete mon;
}

TEST_CASE("Heal pokemon after battle") {
    auto library = TestLibrary::GetLibrary();
    auto c1 = PkmnLib::Battling::CreatePokemon(library, "testSpecies"_cnc, 50)
                  .LearnMove("testMove"_cnc, CreatureLib::Battling::AttackLearnMethod::Unknown)
                  .Build();
    PkmnLib::Battling::PokemonParty party1{c1};
    auto battleParty1 = new CreatureLib::Battling::BattleParty(&party1, {CreatureLib::Battling::CreatureIndex(0, 0)});
    auto c2 = PkmnLib::Battling::CreatePokemon(library, "testSpecies"_cnc, 50)
                  .LearnMove("testMove"_cnc, CreatureLib::Battling::AttackLearnMethod::Unknown)
                  .Build();
    PkmnLib::Battling::PokemonParty party2{c2};
    auto battleParty2 = new CreatureLib::Battling::BattleParty(&party2, {CreatureLib::Battling::CreatureIndex(1, 0)});

    auto battle = new PkmnLib::Battling::Battle(library, {battleParty1, battleParty2});

    REQUIRE_FALSE(battle->HasEnded());

    battle->SwitchCreature(0, 0, c1);
    battle->SwitchCreature(1, 0, c2);

    REQUIRE_FALSE(battle->HasEnded());
    REQUIRE(battle->TrySetChoice(new CreatureLib::Battling::AttackTurnChoice(
        c1, c1->GetAttacks()[0].GetValue(), CreatureLib::Battling::CreatureIndex(1, 0))));
    REQUIRE(battle->TrySetChoice(new CreatureLib::Battling::PassTurnChoice(c2)));

    REQUIRE_FALSE(battle->HasEnded());

    REQUIRE(c2->GetCurrentHealth() < c2->GetBoostedStat(PkmnLib::Library::Statistic::HealthPoints));

    c2->Damage(c2->GetCurrentHealth(), CreatureLib::Battling::DamageSource::AttackDamage);

    REQUIRE(battle->HasEnded());
    auto result = battle->GetResult();
    REQUIRE(result.IsConclusiveResult());
    REQUIRE(result.GetWinningSide() == 0);
    delete battle;
    c2->Heal(1000, true);
    REQUIRE(c2->GetCurrentHealth() == c2->GetMaxHealth());
}

#endif