//
// Filter obviously bad commands to reduce search space for AI
//

#ifndef EAGLE0_AICOMMANDFILTER_HPP
#define EAGLE0_AICOMMANDFILTER_HPP

#include <memory>
#include <vector>

#include "src/main/cpp/net/eagle0/shardok/library/ShardokEngine.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/flatbuffer/net/eagle0/shardok/storage/game_state.hpp"
#include "src/main/protobuf/net/eagle0/shardok/api/command_descriptor.pb.h"

namespace shardok {

using GameState = net::eagle0::shardok::storage::fb::GameState;

/**
 * Filters obviously bad moves to reduce search space for AI.
 * This class implements heuristic filtering to eliminate moves that are
 * strategically bad without requiring deep search to identify.
 */
class AICommandFilter {
public:
    /**
     * Filter a list of commands, removing obviously bad ones.
     * @param commands Original list of all available commands
     * @param pid Player ID making the move
     * @param isDefender True if this player is the defender
     * @param gameState Current game state
     * @param settings Game settings for parameter lookup
     * @param apdCache Action point distance cache for distance calculations
     * @return Filtered list of commands worth evaluating
     */
    static std::vector<size_t> FilterCommands(
            const CommandListSPtr& commands,
            PlayerId pid,
            bool isDefender,
            const GameStateW& gameState,
            const SettingsGetter& settings,
            const APDCache& apdCache);

private:
    // Helper to build enemy locations once for efficiency
    static CoordsSet BuildEnemyLocations(const GameStateW& gameState, PlayerId pid);

    // Spell preparation filters
    static bool IsWastefulAction(
            const ShardokCommand& cmd,
            PlayerId pid,
            bool isDefender,
            const GameStateW& gameState,
            const SettingsGetter& settings,
            const APDCache& apdCache,
            const CoordsSet& enemyLocations,
            const CoordsSet& castleLocations,
            double minDistToEnemies);

    // Movement filters
    static bool IsWastefulMovement(
            const ShardokCommand& cmd,
            PlayerId pid,
            bool isDefender,
            const GameStateW& gameState,
            const SettingsGetter& settings,
            const APDCache& apdCache,
            const CoordsSet& enemyLocations,
            double minDistToEnemies);

    // Strategic blunder filters
    static bool IsStrategicBlunder(
            const ShardokCommand& cmd,
            PlayerId pid,
            bool isDefender,
            const GameStateW& gameState,
            const SettingsGetter& settings,
            double minDistToEnemies);

    // Helper functions for distance and position analysis
    static double MinDistanceToEnemyUnits(
            const GameStateW& gameState,
            PlayerId pid,
            const CoordsSet& enemyLocations);

    static double MinDistanceToCastles(
            const GameStateW& gameState,
            PlayerId pid,
            const CoordsSet& castleLocations);

    static bool IsPlayerOutnumbered(const GameStateW& gameState, PlayerId pid, double threshold);

    static int CountPlayerUnits(const GameStateW& gameState, PlayerId pid);

    static bool WouldAbandonCriticalCastle(
            const ShardokCommand& cmd,
            PlayerId pid,
            const GameStateW& gameState);
};

}  // namespace shardok

#endif  // EAGLE0_AICOMMANDFILTER_HPP