#pragma once

#include <map>
#include <string>
#include <vector>

#include "BuildingId.h"
#include "ItemChipRow.h"
#include "RecipeLineRow.h"
#include "SelectionContent.h"

struct Building;
struct BuildingTarget;
class ProductionSection;
class RecipeLineRow;
class SectionBox;

// Shared body of the four cards that show one building with buffers -- the Miner and
// Assembler, the Smelter and Reprocessing Plant, the Shipyard, and the Salvage Bay
// (REQ-UI-SELECTION-CONTENT). All four show the same header status, recipe summary,
// buffer contents and production progress; they differ only in what one production cycle
// costs and how long it takes, which is what the subclass supplies.
//
// This is implementation sharing, not a catalog entry: every concrete subclass is one
// row of the content catalog.
class BufferedBuildingContent : public SelectionContent
{
    Q_OBJECT

protected:
    // What one production cycle of this building consumes, produces, and takes.
    struct CycleInfo
    {
        std::map<std::string, int> perCycleInputs;
        // What one cycle produces, one entry per output group (REQ-MAT-OUTPUT-GROUP), so
        // the summary can state alternatives as such. The output chips are listed from
        // this too, flattened: a chip stands for a buffer, and a buffer exists for every
        // item any group can produce.
        std::vector<std::vector<RecipeLineRow::Amount>> perCycleOutputGroups;

        // False when the building produces nothing at all (the Salvage Bay,
        // REQ-BLD-SALVAGE-BAY) or has no recipe or schematic selected yet: the
        // production section is then not shown (REQ-UI-PRODUCTION-PROGRESS).
        bool runsProduction = false;
        // 0 only when no recipe describes the cycle at all -- an auto-recipe building
        // that has yet to run one (REQ-UI-RECIPE-SUMMARY). The progress line reads
        // "idle" whenever no cycle is actually running, whatever this says.
        double durationSeconds = 0.0;
    };

    BufferedBuildingContent(const SelectionContext& context, BuildingId id,
                            QWidget* parent);

    // Called with a construction site's stored configuration too, so the summary of what
    // the building will produce is shown before it is built (REQ-BLD-SITE-CONFIG).
    virtual CycleInfo getCycleInfo(const BuildingTarget& target) const = 0;

    // The subclass's own configuration controls. The identity, the recipe summary, the
    // buffers and the production progress are handled here.
    virtual void refreshControls(const BuildingTarget& /*target*/) {}

    BuildingId getBuildingId() const { return m_id; }

private:
    void refreshConfiguration() override;
    void refreshRuntime() override;

    std::vector<ItemChipRow::Entry> buildInputEntries(const Building& building,
                                                      const CycleInfo& cycle) const;
    std::vector<ItemChipRow::Entry> buildOutputEntries(const Building& building,
                                                       const CycleInfo& cycle) const;

    BuildingId m_id;

    RecipeLineRow*    m_recipeSummary;

    // Input buffers, production progress, output buffer -- in that order, so the card
    // reads the way the materials flow (REQ-UI-SINGLE-SELECTION).
    SectionBox*        m_inputSection;
    ItemChipRow*       m_inputChips;
    ProductionSection* m_production;
    SectionBox*        m_outputSection;
    ItemChipRow*       m_outputChips;
};
