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

#include "GraphWidget.h"
#include <QCheckBox>
#include <QComboBox>
#include <QEvent>
#include <QGestureEvent>
#include <QGroupBox>
#include <QMainWindow>
#include <QMessageBox>
#include <QPushButton>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QSettings>
#include <QSwipeGesture>
#include <QTabWidget>
#include <QTextEdit>
#include <QTimer>
#include <QToolBar>

class MainWindow : public QMainWindow {
  Q_OBJECT

public:
  explicit MainWindow(QWidget *parent = nullptr);
  ~MainWindow();

protected:
  bool event(QEvent *event) override;

private slots:
  // Serial Slots
  void handleSerialData();
  void connectToPort();
  void refreshPorts();
  void onPortError(QSerialPort::SerialPortError error);

  // UI Slots
  void onBlinkTimer();
  void onLPFChanged(int index);

  // Action Slots
  void checkDeviceId();
  void runCalibration();
  void startSweep();
  void toggleMeasurement();
  void toggleAmperometry();

  // LSV Slots
  void startLSVBlank();
  void startLSVSample();
  void stopLSV();

  void calibrateCellConstant();

private:
  // Split Implementation Methods
  void setupUi();
  void loadSettings();
  void saveSettings();
  void parseData(const QString &data);
  void handleSwipe(QSwipeGesture *gesture);
  void computeHilbert();
  void performCircleFit();
  void calculateLSVDiff();
  void setButtonBlinking(QPushButton *btn, bool blinking);

  // Sequence Handling
  enum SequenceState { SEQ_IDLE, SEQ_WAIT_BOOT, SEQ_WAIT_CALIB };
  SequenceState currentSequence = SEQ_IDLE;
  QString pendingCommand;
  void initiateSequence(const QString &cmd);

  QSerialPort *serial;
  QSettings *settings;
  QTimer *blinkTimer;
  QPushButton *activeButton = nullptr;
  bool blinkState = false;

  // Views
  GraphWidget *rawGraph;
  GraphWidget *nyquistGraph;
  GraphWidget *ampGraph;
  GraphWidget *lsvGraph;
  QTextEdit *logWidget;

  // Layout Containers
  QTabWidget *mainTabWidget;
  QTabWidget *impGraphTabs;

  // --- Global Controls ---
  QComboBox *portSelector;
  QPushButton *connectBtn;
  QPushButton *checkIdBtn;
  QPushButton *calibrateBtn;
  QComboBox *comboTiaRange;

  // --- Impedance Controls ---
  QDoubleSpinBox *spinSweepStart;
  QDoubleSpinBox *spinSweepStop;
  QSpinBox *spinSweepPPD;
  QPushButton *sweepBtn;

  QDoubleSpinBox *spinFreq;
  QDoubleSpinBox *spinImpBias; // New: Impedance DC Bias
  QPushButton *measureBtn;

  QDoubleSpinBox *spinCondStd;
  QPushButton *btnCalCond;
  QLabel *lblResultRs;
  QLabel *lblResultCond;

  // --- Amperometry Controls ---
  QDoubleSpinBox *spinAmpBias;
  QPushButton *ampBtn;
  QComboBox *comboLPF;

  // --- LSV Controls ---
  QDoubleSpinBox *spinLsvStart;
  QDoubleSpinBox *spinLsvStop;
  QSpinBox *spinLsvSteps;
  QSpinBox *spinLsvDuration;
  QPushButton *lsvBlankBtn;
  QPushButton *lsvSampleBtn;

  // State
  double cellConstant = 1.0;
  bool isMeasuringImp = false;
  bool isMeasuringAmp = false;
  bool isSweeping = false;
  int expectedSweepPoints = 0;

  enum LSVState { LSV_IDLE, LSV_RUNNING_BLANK, LSV_RUNNING_SAMPLE };
  LSVState lsvState = LSV_IDLE;

  // Data Accumulation
  QVector<double> sweepFreqs;
  QVector<double> sweepReals;
  QVector<double> sweepImags;

  struct LSVPoint {
    double voltage;
    double current;
  };
  QVector<LSVPoint> lsvBlankData;
  QVector<LSVPoint> lsvSampleData;
};