//
// Created by Dan Crosby on 6/19/23.
//

#ifndef EAGLE0_AIATTACKGROUPS_HPP
#define EAGLE0_AIATTACKGROUPS_HPP

#include <vector>

#include "src/main/cpp/net/eagle0/shardok/ai/AIAttackLocations.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/flatbuffer/net/eagle0/shardok/storage/player_info.hpp"
#include "src/main/flatbuffer/net/eagle0/shardok/storage/unit.hpp"

namespace shardok {

using GameState = net::eagle0::shardok::storage::fb::GameState;
using Unit = net::eagle0::shardok::storage::fb::Unit;
using net::eagle0::shardok::storage::fb::PlayerInfo;
using std::vector;

struct TargetAndAttackLocations {
    Coords target;
    CoordsSet attackLocations;

    auto operator==(const TargetAndAttackLocations& rhs) const -> bool = default;
};

struct TargetPriorityList {
    UnitId attackingUnitId;
    vector<TargetAndAttackLocations> priorityOrder;

    TargetPriorityList(const UnitId uid, const vector<TargetAndAttackLocations>& po)
        : attackingUnitId(uid),
          priorityOrder(po) {}
};

auto EffectiveDistance(
        const Unit* unit,
        const HexMap* map,
        const MapId& mapId,
        const APDCache& apdCache,
        const AttackLocations& attackLocations,
        const SettingsGetter& settings,
        int braveWaterCost) -> DIST_T;

auto EffectiveDistance(
        const Unit* unit,
        const HexMap* map,
        const MapId& mapId,
        const APDCache& apdCache,
        const CoordsSet& locations,
        const SettingsGetter& settings,
        int braveWaterCost) -> DIST_T;

auto EffectiveDistance(
        const Unit* unit,
        const ActionPointDistances* notBravingApd,
        const ActionPointDistances* bravingApd,
        const CoordsSet& locations) -> DIST_T;

// Chooses a list of targets in priority order for each unit.
auto GenerateTargetPriorities(
        const vector<const Unit*>& occupants,
        const HexMap* map,
        const CoordsSet& targets,
        PlayerId attackerId,
        const vector<const Unit*>& remainingUnits,
        const APDCache& apdCache,
        const ALCache& alCache,
        const MapId& mapId,
        const SettingsGetter& settings,
        bool isLateGame = false) -> vector<TargetPriorityList>;

}  // namespace shardok

#endif  // EAGLE0_AIATTACKGROUPS_HPP
