#pragma once

#include <vector>

#include <QString>
#include <QWidget>

#include "entt/entity/entity.hpp"

#include "DebugDrawToggledEvent.h"
#include "EventHandler.h"
#include "PlayerCommandsAppliedEvent.h"
#include "TickAdvancedEvent.h"

struct GameConfig;
class Simulation;
class ShipStatsPanel;
class QLabel;
class QVBoxLayout;

// Renders the "field" selection category — ships, defence stations and debris — as either
// a single-object stats panel (ship, station, or debris) or a compact multi-object count
// summary (REQ-UI-SELECTION-CATEGORIES, REQ-UI-FIELD-MULTI-SELECTION, REQ-UI-DEBRIS-PANEL).
//
// The panel owns its own selection state and its own widgets, and nothing else. Which of
// the two selection categories owns the side panel is arbitrated by the parent
// SelectedBuildingPanel: it feeds this panel through setSelectedEntities() /
// setSelectedDebris() / clearSelection() and asks it via hasSelection(). This panel hides
// itself whenever its selection is empty, so an inactive field category takes no space.
class FieldSelectionPanel : public QWidget,
                            public CombinedEventHandler<TickAdvancedEvent,
                                                        PlayerCommandsAppliedEvent,
                                                        DebugDrawToggledEvent>
{
    Q_OBJECT

public:
    FieldSelectionPanel(Simulation* sim, const GameConfig* config,
                        QWidget* parent = nullptr);
    ~FieldSelectionPanel() override;

    // Replaces the selected actors (ships and defence stations); debris is left alone,
    // the two coexist within the field category (REQ-UI-SELECTION-CATEGORIES).
    void setSelectedEntities(const std::vector<entt::entity>& entities);
    // Replaces the selected debris; the selected actors are left alone.
    void setSelectedDebris(const std::vector<entt::entity>& debris);
    // Drops the whole field selection — used when the building category takes over.
    void clearSelection();
    // True while the field category has anything selected, i.e. while this panel owns
    // the side panel's content.
    bool hasSelection() const;

private:
    void handleEvent(std::shared_ptr<const TickAdvancedEvent> event) override;
    void handleEvent(std::shared_ptr<const PlayerCommandsAppliedEvent> event) override;
    void handleEvent(std::shared_ptr<const DebugDrawToggledEvent> event) override;

    // Picks the layout for the current selection and shows/hides this panel accordingly.
    void rebuild();
    // Keeps the live values of the layout chosen by rebuild() current.
    void refreshDisplay();
    void buildEntityShip(entt::entity entity);
    void buildEntityStation(entt::entity entity);
    void buildEntitySummary();
    void buildDebrisSingle();
    void refreshEntityStats();
    void hideAllWidgets();
    // Summed remaining scrap across the selected debris (REQ-UI-DEBRIS-PANEL).
    int selectedDebrisScrapTotal() const;
    // "Scrap x N" line for the multi-object summary (REQ-UI-FIELD-MULTI-SELECTION).
    QString scrapTotalText() const;

    Simulation*       m_sim;
    const GameConfig* m_config;

    bool m_debugDraw = false;

    // The selected ships/defence stations. Shares the "field" selection category with
    // debris (m_selectedDebris): both can be non-empty at once (REQ-UI-SELECTION-CATEGORIES).
    std::vector<entt::entity> m_selectedEntities;
    std::vector<entt::entity> m_selectedDebris;

    QVBoxLayout*    m_layout;
    QLabel*         m_entityTitleLabel;
    ShipStatsPanel* m_entityStatsPanel;
    QLabel*         m_stationStatsLabel;
    QLabel*         m_entitySummaryLabel;
    // Shows the debris "Scrap" stat row (single selection) — the scrap total for the
    // multi-object summary lives in m_entitySummaryLabel instead.
    QLabel*         m_scrapLabel;
};
