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

#ifndef EAGLE0_REDUCECOMMAND_HPP
#define EAGLE0_REDUCECOMMAND_HPP

#include <utility>

#include "src/main/cpp/net/eagle0/shardok/library/ShardokCommand.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/map/Coordinates.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/settings/GameSettings.hpp"
#include "src/main/protobuf/net/eagle0/shardok/common/terrain.pb.h"

namespace shardok {

using TerrainProto = net::eagle0::shardok::common::Terrain;

class ReduceCommand : public ShardokCommand {
private:
    [[nodiscard]] auto ExecuteWithRoll(const GameStateW& currentState, double roll) const
            -> vector<ActionResult>;

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

    const ActionCost cost;
    const UnitId actorId;
    const Coords target;
    const double forestBonus;
    const double averageReduceDebuf;
    const double unitDamagePerReduceDebuf;
    const int agilityXp;
    const int strengthXp;
    const int minimumKnowledge;
    const SettingsGetter settings;

public:
    ReduceCommand(
            const ActionCost& cost,
            const PlayerId playerId,
            const UnitId actorId,
            Coords target,
            const double forestBonus,
            const double averageReduceDebuf,
            const double unitDamagePerReduceDebuf,
            const int agilityXp,
            const int strengthXp,
            const int minimumKnowledge,
            const SettingsGetter& settingsGetter)
        : ShardokCommand(playerId),
          cost(cost),
          actorId(actorId),
          target(std::move(target)),
          forestBonus(forestBonus),
          averageReduceDebuf(averageReduceDebuf),
          unitDamagePerReduceDebuf(unitDamagePerReduceDebuf),
          agilityXp(agilityXp),
          strengthXp(strengthXp),
          minimumKnowledge(minimumKnowledge),
          settings(settingsGetter){};

    ~ReduceCommand() override = default;

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

    [[nodiscard]] auto GetCommandProto() const -> CommandProto override;

    [[nodiscard]] auto IsRequiredToEndTurn() const -> bool override { return false; }
    [[nodiscard]] auto CanBeFollowUp() const -> bool override { return true; }
    [[nodiscard]] auto CanDoWithLowMorale() const -> bool override { return false; }
    [[nodiscard]] auto CanDoWhileStunned() const -> bool override { return false; }
    [[nodiscard]] auto CanDoWithLowVigor() const -> bool override { return false; }
    [[nodiscard]] auto CanDoAfterMovingIntoZoc() const -> bool override { return false; }
};
}  // namespace shardok

#endif  // EAGLE0_REDUCECOMMAND_HPP
