// File: host/src/GraphWidget.h
#pragma once

#include <QWidget>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QDialog>
#include <QComboBox>
#include <QSpinBox>
#include <QCheckBox>
#include "qcustomplot.h"

class GraphWidget : public QWidget {
    Q_OBJECT

public:
    explicit GraphWidget(QWidget *parent = nullptr);
    
    // Data Handling
    void addBodeData(double freq, double val1, double val2);
    void addNyquistData(double r_meas, double i_meas, double r_corr, double i_corr, bool showCorr);
    void addAmperometricData(double index, double current);
    
    enum LSVTrace { LSV_BLANK, LSV_SAMPLE, LSV_DIFF };
    void addLSVData(double voltage, double current, LSVTrace traceType);
    
    void addHilbertData(const QVector<double>& freq, const QVector<double>& hilbertImag);
    void setExtrapolatedPoint(double real, double imag);
    
    void clear();
    void clearLSV(LSVTrace traceType);
    
    // View Configurations
    void configureRawPlot();
    void configureNyquistPlot();
    void configureAmperometricPlot();
    void configureLSVPlot();

private slots:
    void scaleX();
    void scaleY();
    void scaleBoth();
    void centerView();
    void startAnalyze();

private:
    QVBoxLayout *mainLayout;
    QCustomPlot *plot;
    
    // Toolbar
    QWidget *toolbar;
    QPushButton *btnScaleX;
    QPushButton *btnScaleY;
    QPushButton *btnScaleBoth;
    QPushButton *btnCenter;
    QPushButton *btnAnalyze;
    
    // Graphs
    QCPGraph *graphReal; 
    QCPGraph *graphImag; 
    QCPGraph *graphHilbert; 
    QCPGraph *graphNyquistRaw;
    QCPGraph *graphNyquistCorr;
    QCPGraph *graphExtrapolated;
    QCPGraph *graphAmp;
    QCPGraph *graphLSVBlank;
    QCPGraph *graphLSVSample;
    QCPGraph *graphLSVDiff;
    QCPGraph *graphFit; // For analysis results

    // Analysis State
    bool isSelecting = false;
    QCPItemRect *selectionRect;
    double selStartX, selStartY;
    
    void performFit(const QVector<double>& x, const QVector<double>& y, int type, int order, bool inverse);
};