#pragma once

#include <optional>

#include <QColor>
#include <QPixmap>
#include <QString>
#include <QWidget>

#include "BuildingId.h"
#include "BuildingType.h"
#include "SelectionContext.h"

struct Building;
class BarRow;
class QLabel;
class QVBoxLayout;
class SectionBox;
class StatusPill;

// One card of the selection panel: the content shown for a particular kind of selection
// (REQ-UI-SELECTION-CARD). Every content is this base plus the parts its constructor
// puts into the two groups; which content is shown for which selection is decided in
// SelectionContentFactory (REQ-UI-SELECTION-CONTENT).
//
// The card has three parts, top to bottom:
//   * the header  -- identity symbol, name, and one optional right slot (a status
//     indicator, a ship's behavior, or an object count);
//   * the configuration group -- controls that change how the object is set up;
//   * the runtime group -- what the object is currently doing.
//
// A construction site keeps its configuration group and has its whole runtime group
// replaced by the construction section (REQ-BLD-SITE-CONFIG). That rule lives here and
// nowhere else: a subclass fills both groups unconditionally in its constructor and
// never asks whether it is showing a site.
class SelectionContent : public QWidget
{
    Q_OBJECT

public:
    ~SelectionContent() override;

    // Re-reads the live values behind the card. It never changes the card's structure:
    // a change that would (a site finishing, the selection changing) is a rebuild, and
    // SelectionPanel owns that decision.
    void refresh();

    // The card's header (REQ-UI-SELECTION-CARD), which is also the handle the panel is
    // dragged by (REQ-UI-SELECTION-PANEL-DRAG). The panel hit-tests against it; the card
    // itself does nothing with the gesture.
    QWidget* getHeaderWidget() const { return m_header; }

protected:
    // constructionSiteId is set only while the card shows a construction site, in which
    // case this base builds and drives the construction section in place of whatever the
    // subclass puts into the runtime group.
    SelectionContent(const SelectionContext& context,
                     std::optional<BuildingId> constructionSiteId,
                     QWidget* parent);

    // Live values of the runtime group. Not called while the card shows a construction
    // site, which has neither buffers nor a production cycle (REQ-BLD-SITE-CONFIG).
    virtual void refreshRuntime() = 0;

    // Live values of the configuration group. Called for a site too, because a site is
    // configured exactly like the building it will become (REQ-BLD-SITE-CONFIG).
    virtual void refreshConfiguration() {}

    const SelectionContext& getContext() const { return m_context; }

    // The two group layouts a subclass adds its parts to, in its constructor.
    QVBoxLayout* getConfigurationLayout();
    QVBoxLayout* getRuntimeLayout();

    void setIdentity(const QPixmap& symbol, const QString& name);
    // Header symbol for a building type: its chip icon, or nothing when the icon file is
    // missing -- which is not an error (REQ-UI-BUILD-ICON, REQ-UI-SELECTION-CARD).
    void setBuildingIdentity(BuildingType type, const QString& name);

    // Fills the header's right slot. A null dot color leaves the dot off, for the slots
    // that are a plain caption (a construction site, a ship's behavior).
    void setSlot(const QColor& dotColor, const QString& caption);
    // "x<count>", for an aggregated multi-selection (REQ-UI-SELECTION-AGGREGATE).
    void setCountSlot(int count);
    void clearSlot();

    // Fills the right slot from the building's production status, mapped to the same
    // colors and states the world's status light uses (REQ-UI-SELECTION-STATUS). Leaves
    // the slot empty for a type that has no status light.
    void setProductionStatusSlot(const Building& building);

private:
    void refreshConstruction();

    SelectionContext m_context;
    // Set while this card shows a construction site rather than a finished object.
    std::optional<BuildingId> m_siteId;

    QWidget*    m_header;
    QLabel*     m_symbolLabel;
    QLabel*     m_nameLabel;
    StatusPill* m_statusPill;

    QWidget* m_configurationGroup;
    QWidget* m_runtimeGroup;
    // Replaces the runtime group while this card shows a construction site; both null
    // otherwise.
    SectionBox* m_constructionSection;
    BarRow*     m_constructionBar;
};
