#include "DeliverScrapEvaluator.h"
#include "FactoryQueries.h"

#include <unordered_map>

#include "BehaviorScores.h"
#include "BehaviorTargeting.h"
#include "Building.h"
#include "BuildingSystem.h"
#include "BuildingType.h"
#include "DeliverScrapBehavior.h"
#include "EntityAdmin.h"
#include "PositionComponent.h"
#include "tracing.h"

void DeliverScrapEvaluator::evaluate(EntityAdmin& admin, const FactoryState& state)
{
    TRACE();
    const std::unordered_map<entt::entity, CargoState> cargoByShip = buildCargoByShip(admin);

    admin.forEach<DeliverScrapBehavior, PositionComponent>(
        [&](entt::entity e, DeliverScrapBehavior& deliver, const PositionComponent& pos)
        {
            const std::unordered_map<entt::entity, CargoState>::const_iterator it =
                cargoByShip.find(e);
            const bool cargoFull = (it != cargoByShip.end()) && isCargoFull(it->second);

            if (!cargoFull)
            {
                deliver.score = BehaviorScores::kInactive;
                return;
            }

            // Assign nearest SalvageBay if not yet assigned.
            if (!deliver.deliveryBay.has_value())
            {
                const Building* bay =
                    findNearestBuilding(state, pos.value, BuildingType::SalvageBay);
                if (bay) { deliver.deliveryBay = bay->id; }
            }

            deliver.score = BehaviorScores::kDeliver;
        });
}
