//
// Created by Dan Crosby on 5/16/20.
//

#ifndef EAGLE0_ARCHERYCOMMAND_HPP
#define EAGLE0_ARCHERYCOMMAND_HPP

#include "src/main/cpp/net/eagle0/shardok/library/ShardokCommand.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/settings/GameSettings.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/unit/Unit.hpp"

namespace shardok {

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

class ArcheryCommand : public ShardokCommand {
private:
    [[nodiscard]] auto ExecuteWithRolls(
            const GameStateW& currentState,
            double ambushRoll,
            double attackerRoll) const -> vector<ActionResult>;

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

    const SettingsGetter settings;
    const UnitId attackerId;
    const UnitId defenderId;
    const Coords defenderLocation;
    const PercentileRollOdds ambushOdds;
    const Terrain defenderTerrain;

public:
    ArcheryCommand(
            const SettingsGetter& settingsGetter,
            PlayerId attackerPlayerId,
            UnitId attackerId,
            UnitId defenderId,
            const Coords& defenderLocation,
            PercentileRollOdds ambushOdds,
            const Terrain& defenderTerrain);

    ~ArcheryCommand() override = default;

    auto GetCommandType() const -> CommandType override {
        return net::eagle0::shardok::common::ARCHERY_COMMAND;
    }

    auto CanUseClientRoll() const -> bool override { return true; }

    auto GetCommandProto() const -> CommandProto override;
};
}  // namespace shardok

#endif  // EAGLE0_ARCHERYCOMMAND_HPP
