//
// Factory implementation for creating Shardok-specific MCTS components
//

#include "ShardokMCTSFactory.hpp"

#include "ShardokAction.hpp"
#include "ShardokGameEngine.hpp"
#include "ShardokGameState.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/ShardokEngine.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/settings/GameSettings.hpp"

namespace shardok::mcts {

std::unique_ptr<MCTSGameEngine> ShardokMCTSFactory::createGameEngine(
        const ShardokEngine& engine,
        const AIScoreCalculator* scoreCalculator,
        const GameSettingsSPtr& gameSettings,
        const APDCache& apdCache,
        const ALCache& alCache,
        bool isDefender,
        const AIStrategy& strategy,
        const CoordsSet& castleCoords,
        const CoordsSet& criticalTileCoords) {
    return std::make_unique<ShardokGameEngine>(
            &engine,
            scoreCalculator,
            gameSettings,
            &apdCache,
            &alCache,
            isDefender,
            strategy,
            castleCoords,
            criticalTileCoords);
}

std::unique_ptr<MCTSGameState> ShardokMCTSFactory::createGameState(
        const GameStateW& state,
        const AIScoreCalculator* scoreCalculator,
        const GameSettingsSPtr& settings,
        bool isDefender,
        const AIStrategy& strategy,
        const CoordsSet& castleCoords,
        const APDCache& apdCache,
        const ALCache& alCache,
        const CoordsSet& criticalTileCoords) {
    return std::make_unique<ShardokGameState>(
            state,
            scoreCalculator,
            settings.get(),  // Get raw pointer from shared_ptr
            isDefender,
            strategy,
            castleCoords,
            apdCache,
            alCache,
            criticalTileCoords);
}

std::vector<std::unique_ptr<MCTSAction>> ShardokMCTSFactory::createActionsFromCommandList(
        const CommandListSPtr& commands) {
    std::vector<std::unique_ptr<MCTSAction>> actions;
    if (!commands) { return actions; }

    actions.reserve(commands->size());
    for (size_t i = 0; i < commands->size(); ++i) {
        const auto& cmd = (*commands)[i];

        // Extract essential fields directly from command (no proto conversion!)
        actions.push_back(std::make_unique<ShardokAction>(
                i,
                cmd->GetCommandType(),
                cmd->GetPlayerId(),
                cmd->GetActorUnitId(),
                cmd->GetTargetRow(),
                cmd->GetTargetColumn(),
                cmd->HasOdds()));
    }

    return actions;
}

}  // namespace shardok::mcts