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

#ifndef EAGLE0_SHARDOK_MCTS_FACTORY_HPP
#define EAGLE0_SHARDOK_MCTS_FACTORY_HPP

#include <functional>
#include <memory>
#include <vector>

#include "src/main/cpp/net/eagle0/shardok/ai/AIAttackLocations.hpp"
#include "src/main/cpp/net/eagle0/shardok/ai/AIStrategy.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/ShardokCTypes.h"
#include "src/main/cpp/net/eagle0/shardok/library/ShardokCommand.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/action_point_distances/ActionPointDistancesCache.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/map/CoordsSet.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/settings/GameSettings.hpp"
#include "src/main/protobuf/net/eagle0/shardok/api/command_descriptor.pb.h"

namespace shardok {

// Forward declarations
class ShardokEngine;
class AICommandFilter;
class AIScoreCalculator;
class GameStateW;
class GameSettings;

// Use existing type definitions to avoid conflicts
// These are already defined in the Shardok codebase:
// - APDCache in ActionPointDistancesCache.hpp
// - ALCache in AIAttackLocations.hpp
// - CommandListSPtr in ShardokCommand.hpp
// - SettingsGetter in GameSettings.hpp
using CommandProto = net::eagle0::shardok::api::CommandDescriptor;

namespace mcts {

// Forward declarations
class MCTSGameEngine;
class MCTSGameState;
class MCTSAction;

class ShardokMCTSFactory {
public:
    using CommandProto = net::eagle0::shardok::api::CommandDescriptor;

    // Create a Shardok game engine adapter
    [[nodiscard]] static std::unique_ptr<MCTSGameEngine> createGameEngine(
            const ShardokEngine& engine,
            const AICommandFilter* commandFilter,
            const AIScoreCalculator* scoreCalculator,
            const GameSettingsSPtr& gameSettings,
            const APDCache& apdCache,
            const ALCache& alCache,
            PlayerId playerId,
            bool isDefender,
            const AIStrategy& strategy,
            const CoordsSet& castleCoords,
            const CoordsSet& criticalTileCoords);

    // Create a Shardok game state adapter
    [[nodiscard]] static std::unique_ptr<MCTSGameState> 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);

    // Convert Shardok commands to MCTS actions
    [[nodiscard]] static std::vector<std::unique_ptr<MCTSAction>> createActions(
            const std::vector<CommandProto>& commands);

    // Convert from command list to MCTS actions
    [[nodiscard]] static std::vector<std::unique_ptr<MCTSAction>> createActionsFromCommandList(
            const CommandListSPtr& commands);
};

}  // namespace mcts
}  // namespace shardok

#endif  // EAGLE0_SHARDOK_MCTS_FACTORY_HPP