//
// Created by Claude on 3/14/26.
//

#ifndef EAGLE0_BLOWBRIDGECOMMAND_HPP
#define EAGLE0_BLOWBRIDGECOMMAND_HPP

#include <utility>

#include "src/main/cpp/net/eagle0/shardok/library/ActionCost.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/ShardokCommand.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/map/Coordinates.hpp"

namespace shardok {

using Terrain = net::eagle0::shardok::storage::fb::Terrain;
using Unit = net::eagle0::shardok::storage::fb::Unit;

class BlowBridgeCommand : public ShardokCommand {
protected:
    [[nodiscard]] auto InternalExecuteWithRoll(
            const GameStateW& currentState,
            const std::shared_ptr<RandomGenerator>& generator,
            std::optional<int32_t> roll) const -> vector<ActionResult> override;

    const ActionCost cost;
    const UnitId actorId;
    const Coords target;
    const Coords bridgeCoords;
    const Terrain targetTerrain;
    const bool hasNearbyForest;
    const int agilityXp;
    const int strengthXp;
    int minimumKnowledgeAfter;
    const PercentileRollOdds successOdds;

public:
    BlowBridgeCommand(
            const ActionCost& cost,
            PlayerId playerId,
            UnitId actorId,
            Coords target,
            Coords bridgeCoords,
            const Terrain& targetTerrain,
            bool hasNearbyForest,
            int agilityXp,
            int strengthXp,
            int opponentKnowledgeIncrease,
            PercentileRollOdds successOdds)
        : ShardokCommand(playerId),
          cost(cost),
          actorId(actorId),
          target(std::move(target)),
          bridgeCoords(std::move(bridgeCoords)),
          targetTerrain(std::move(targetTerrain)),
          hasNearbyForest(hasNearbyForest),
          agilityXp(agilityXp),
          strengthXp(strengthXp),
          minimumKnowledgeAfter(opponentKnowledgeIncrease),
          successOdds(std::move(successOdds)){};

    auto ExecuteWithRoll(const GameStateW& currentState, double roll) const -> vector<ActionResult>;

    ~BlowBridgeCommand() override = default;

    [[nodiscard]] auto GetCommandType() const -> CommandType override {
        return net::eagle0::shardok::common::BLOW_BRIDGE_COMMAND;
    }

    [[nodiscard]] auto CanUseClientRoll() const -> bool override { return true; }
    [[nodiscard]] auto GetCommandProto() const -> CommandProto override;

    [[nodiscard]] auto HasOdds() const -> bool override { return true; }
    [[nodiscard]] auto GetOddsPercentile() const -> int32_t override;

    [[nodiscard]] int GetActorUnitId() const override { return actorId; }
    [[nodiscard]] MapIndex GetTargetRow() const override { return target.row(); }
    [[nodiscard]] MapIndex GetTargetColumn() const override { return target.column(); }
};
}  // namespace shardok

#endif  // EAGLE0_BLOWBRIDGECOMMAND_HPP
