#include "AutoProductionContent.h"

#include "Building.h"
#include "BuildingTarget.h"
#include "GameConfig.h"
#include "ProductionRules.h"

AutoProductionContent::AutoProductionContent(const SelectionContext& context,
                                             const SelectionRequest& request,
                                             QWidget* parent)
    : BufferedBuildingContent(context, request.buildings.front(), parent)
{
}

BufferedBuildingContent::CycleInfo AutoProductionContent::getCycleInfo(
    const BuildingTarget& target) const
{
    CycleInfo info;
    // An auto-recipe building always runs an implicit recipe (REQ-BLD-SMELTER,
    // REQ-BLD-REPROCESSING), so its production section is always shown -- but only a
    // running cycle names a recipe, so while it is idle there is no cycle to describe.
    info.runsProduction = true;

    if (target.building)
    {
        // What the building handles at all, so its buffers are not blank whenever it
        // happens to be between cycles (REQ-UI-SINGLE-SELECTION). This is the same union
        // of every recipe of its type that the simulation sized the buffers over, and
        // the locked ones among them are dropped when the card lists them.
        for (const RecipeDef* recipe :
             gatherCandidateRecipes(*getContext().config, *target.building))
        {
            for (const RecipeIngredient& ingredient : recipe->inputs)
            {
                info.handledInputs.push_back(ingredient.item);
            }
            for (const RecipeOutput& output : recipe->outputs)
            {
                info.handledOutputs.push_back(output.item);
            }
        }
    }

    // Which recipe describes the cycle: the one running, or -- between cycles -- the one
    // that ran last. Dropping it while idle would take the summary row and the chips'
    // per-cycle amounts away and bring them back with every cycle, resizing the card in
    // step with the building's status (REQ-UI-RECIPE-SUMMARY). Only a building that has
    // never run has nothing to describe.
    if (target.building && target.building->production.has_value())
    {
        m_lastRecipeId = target.building->production->recipeId;
    }
    if (!target.building || m_lastRecipeId.empty())
    {
        return info;
    }

    const RecipeDef* recipe =
        getContext().config->recipes.findRecipeDef(m_lastRecipeId, target.type);
    if (!recipe)
    {
        return info;
    }

    for (const RecipeIngredient& ingredient : recipe->inputs)
    {
        info.perCycleInputs[ingredient.item] = ingredient.amount;
    }
    for (const RecipeOutput& output : recipe->outputs)
    {
        info.perCycleOutputs[output.item] = output.amount;
    }
    info.durationSeconds = recipe->durationSeconds;
    return info;
}
