/**
 * @file PlotWidget.h
 * @brief Oscilloscope plot panel (custom QPainter), one per grid cell.
 *
 * Mirrors the ImGui PlotPanel: fixed +/-4 division Y space, wall-clock live X
 * window, LTTB decimation, normal/digital/mixed normalization, A/B cursors,
 * scroll/drag zoom + pan, zoom history, hi-res WS zoom + history zoom, and a
 * trigger-capture view rendered in [-pre, +post].
 */

#pragma once

#include "Model.h"

#include <QWidget>
#include <QString>
#include <vector>
#include <utility>
#include <string>

class QHBoxLayout;
class QToolButton;
class QLabel;

namespace shq {

class Hub;

/** View state shared (synchronised) across all plots; owned by MainWindow. */
struct GlobalView {
    double windowSec = 10.0;   /* live scroll window width */
    bool   paused    = false;  /* global pause */
    bool   cursorsOn = false;
    double cursorA   = 0.0;
    double cursorB   = 0.0;
    bool   trigView  = false;  /* trigger bar open → render capture */
};

class PlotCanvas;

class PlotWidget : public QWidget {
    Q_OBJECT
public:
    PlotWidget(Hub* hub, GlobalView* gv, int plotIdx, QWidget* parent = nullptr);

    std::vector<PlotAssignment>& slots() { return slots_; }
    void addAssignment(int sourceIdx, int signalIdx);

    /** Called by MainWindow when sources/config change so badges refresh. */
    void onModelChanged();
    /** Called by MainWindow when global pause toggles. */
    void onPauseChanged();
    /** Reset zoom/live state (e.g. when entering/leaving history mode). */
    void setLive(bool live);
    bool isLive() const { return live_; }
    void setStoredX(double mn, double mx);
    double xMin() const { return plotXMin_; }
    double xMax() const { return plotXMax_; }

    int plotIdx() const { return plotIdx_; }

public Q_SLOTS:
    void onZoomReceived(int plotIdx);
    void onHistoryZoomReceived(int plotIdx);
    void onCaptureReceived();
    void tick();   /* ~60 Hz repaint + throttled zoom requests */

private:
    friend class PlotCanvas;

    void rebuildHeader();
    void showBadgeMenu(int slotIdx, const QPoint& globalPos);
    void pushZoomHist();
    void initPlotX(double tMax);

    Hub*        hub_;
    GlobalView* gv_;
    int         plotIdx_;

    PlotCanvas* canvas_   = nullptr;
    QHBoxLayout* headerLay_ = nullptr;
    QWidget*    header_    = nullptr;
    QLabel*     cursorLbl_ = nullptr;

    std::vector<PlotAssignment> slots_;
    bool   live_       = true;
    bool   paused_     = false;
    double plotXMin_   = 0.0;
    double plotXMax_   = 0.0;
    int    vMode_      = 0;     /* 0 normal 1 digital 2 mixed */
    int    activeSlot_ = -1;
    bool   trigZoomed_ = false;

    std::vector<std::pair<double,double>> zoomHist_;

    /* Paused view snapshot (double buffer). */
    struct Snapshot {
        bool valid = false;
        std::vector<std::string>         keys;
        std::vector<std::vector<double>> t, v;
    } snap_;

    /* Throttle timers (ms wall clock). */
    double lastLiveZoomMs_  = 0.0;
    double rangeChangedMs_  = 0.0;
    double lastT0_ = 0.0, lastT1_ = 0.0;
    double lastHistPushMs_  = 0.0;
};

} /* namespace shq */
