//
// GamePhaseRunner Implementation
//

#include "GamePhaseRunner.hpp"

#include "src/main/cpp/net/eagle0/shardok/ai/ShardokAIClient.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/ShardokEngine.hpp"
#include "src/main/flatbuffer/net/eagle0/shardok/storage/game_state.hpp"

namespace shardok::ai_testing_common {

auto GamePhaseRunner::RunSetupPhase(
        ShardokEngine& engine,
        const std::function<ShardokAIClient&(PlayerId)>& getAI) -> PhaseResult {
    PhaseResult result;

    while (engine.GetCurrentGameState()->status()->state() ==
           net::eagle0::shardok::storage::fb::GameStatus_::State_SET_UP) {
        auto currentState = engine.GetCurrentGameState();
        PlayerId currentPlayer = currentState->current_player();

        auto availableCommands = engine.GetAvailableCommandProtos(currentPlayer, false);

        if (availableCommands.empty()) { break; }

        // Get AI for current player and make decision
        ShardokAIClient& activeAI = getAI(currentPlayer);
        auto choiceResults = activeAI.ChooseCommandIndex(engine);

        // Apply command
        engine.PostCommand(currentPlayer, choiceResults.chosenIndex);
        result.commandsExecuted++;

        // Check if game ended unexpectedly
        if (engine.GameIsOver()) {
            result.gameEnded = true;
            break;
        }
    }

    return result;
}

auto GamePhaseRunner::RunSingleTurn(ShardokEngine& engine, PlayerId playerId, ShardokAIClient& ai)
        -> bool {
    auto availableCommands = engine.GetAvailableCommandProtos(playerId, false);

    if (availableCommands.empty()) { return false; }

    // Get AI decision
    auto choiceResults = ai.ChooseCommandIndex(engine);

    // Apply command
    engine.PostCommand(playerId, choiceResults.chosenIndex);

    return true;
}

}  // namespace shardok::ai_testing_common
