#include "RecipeProductionContent.h"

#include <QVBoxLayout>

#include "BuildingTarget.h"
#include "GameConfig.h"
#include "RecipeSelectionControl.h"
#include "Simulation.h"

RecipeProductionContent::RecipeProductionContent(const SelectionContext& context,
                                                 const SelectionRequest& request,
                                                 QWidget* parent)
    : BufferedBuildingContent(context, request.buildings.front(), parent)
{
    const BuildingTarget target = resolveBuildingTarget(context, getBuildingId());

    // Shown for a construction site too: a site is configured exactly like the building
    // it will become (REQ-BLD-SITE-CONFIG).
    m_recipeControl = new RecipeSelectionControl(context, getBuildingId(), target.type,
                                                 this);
    getConfigurationLayout()->insertWidget(0, m_recipeControl);
}

void RecipeProductionContent::refreshControls(const BuildingTarget& target)
{
    m_recipeControl->setRecipeId(target.recipeId);
}

BufferedBuildingContent::CycleInfo RecipeProductionContent::getCycleInfo(
    const BuildingTarget& target) const
{
    CycleInfo info;
    const RecipeDef* recipe = target.recipeId.empty()
        ? nullptr
        : getContext().config->recipes.findRecipeDef(target.recipeId, target.type);
    if (!recipe)
    {
        return info;
    }

    for (const RecipeIngredient& ingredient : recipe->inputs)
    {
        info.perCycleInputs[ingredient.item] = ingredient.amount;
    }
    // Only what this building can actually be handed (REQ-LOCK-OUTPUT-POOL): a
    // Reprocessing Plant states the alternatives it will roll between, not every
    // alternative its recipe lists. The output chips come from this too, so the buffers
    // beneath the summary agree with it.
    const Simulation* sim = getContext().sim;
    info.perCycleOutputGroups = RecipeLineRow::toUnlockedOutputGroups(
        *recipe,
        [sim](const std::string& itemId) { return sim->isItemUnlocked(itemId); });
    info.runsProduction  = true;
    info.durationSeconds = recipe->durationSeconds;
    return info;
}
