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

#include "MeteorStartCommand.hpp"

#include "src/main/cpp/net/eagle0/shardok/library/actions/ActionRequiresHeroException.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/unit/Unit.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/util/ActionResultFlatbufferHelpers.hpp"

namespace shardok {

MeteorStartCommand::MeteorStartCommand(
        const shardok::ActionCost &cost,
        const shardok::SettingsGetter &settingsGetter,
        const PlayerId playerId,
        const UnitId casterId,
        const CoordsSet &nextRoundTargets)
    : ShardokCommand(playerId),
      cost(cost),
      settings(settingsGetter),
      casterId(casterId),
      nextRoundTargets(nextRoundTargets) {}

auto MeteorStartCommand::GetCommandProto() const -> CommandProto {
    CommandProto proto{};

    proto.set_player(GetPlayerId());
    proto.set_type(net::eagle0::shardok::common::METEOR_START_COMMAND);
    proto.mutable_actor()->set_value(casterId);
    for (const Coords &c : nextRoundTargets) {
        *proto.mutable_next_round_target_info()->add_targets() = ToCoordsProto(c);
    }
    proto.mutable_next_round_target_info()->set_type(
            net::eagle0::shardok::common::METEOR_TARGET_COMMAND);

    return proto;
}

auto MeteorStartCommand::InternalExecute(
        const GameStateW &currentState,
        const std::shared_ptr<RandomGenerator> &generator) const -> vector<ActionResult> {
    const auto *caster = currentState->units()->Get(casterId);

    auto casterAfter = *caster;
    MutatingSpendActionPoints(&casterAfter, cost);

    auto &mutableHero = casterAfter.mutable_attached_hero();
    mutableHero.mutable_profession_info().mutate_meteor_cast_state(
            net::eagle0::shardok::storage::fb::MultiroundMagicState_START);
    mutableHero.mutable_profession_info().mutable_cast_target() = Coords(-1, -1);

    ActionResult result{};
    result.set_type(net::eagle0::shardok::common::METEOR_START);
    result.mutable_player()->set_value(GetPlayerId());
    result.mutable_actor()->set_value(casterId);
    AddChangedUnit(result, casterAfter);

    return {result};
}

}  // namespace shardok
