// File: host/src/MainWindow_UI.cpp
#include "MainWindow.h"
#include <QFrame>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QLabel>
#include <QScroller>
#include <QVBoxLayout>

void MainWindow::setupUi() {
  QWidget *central = new QWidget(this);
  setCentralWidget(central);
  QVBoxLayout *mainLayout = new QVBoxLayout(central);
  mainLayout->setContentsMargins(2, 2, 2, 2);
  mainLayout->setSpacing(2);

  // ========================================================================
  // 1. Global Toolbar (Connection & Hardware Settings)
  // ========================================================================
  QGroupBox *globalGroup = new QGroupBox("Connection & Hardware", this);
  globalGroup->setStyleSheet(
      "QGroupBox { font-weight: bold; border: 1px solid #555; border-radius: "
      "4px; margin-top: 6px; } QGroupBox::title { subcontrol-origin: margin; "
      "left: 10px; padding: 0 3px; }");
  QVBoxLayout *globalLayout = new QVBoxLayout(globalGroup);
  globalLayout->setContentsMargins(4, 12, 4, 4);
  globalLayout->setSpacing(4);

  // Row 1: Connection
  QHBoxLayout *connLayout = new QHBoxLayout();
  portSelector = new QComboBox(this);
  portSelector->setMinimumWidth(120);
  connectBtn = new QPushButton("Connect", this);
  connectBtn->setStyleSheet("background-color: rgba(0, 128, 0, 128); color: "
                            "white; font-weight: bold;");
  QPushButton *refreshBtn = new QPushButton("Refresh", this);
  checkIdBtn = new QPushButton("Check ID", this);

  connLayout->addWidget(portSelector, 1);
  connLayout->addWidget(connectBtn);
  connLayout->addWidget(refreshBtn);
  connLayout->addWidget(checkIdBtn);
  globalLayout->addLayout(connLayout);

  // Row 2: Hardware Config
  QHBoxLayout *hwLayout = new QHBoxLayout();

  comboTiaRange = new QComboBox(this);
  comboTiaRange->setToolTip("High Speed TIA Range");
  comboTiaRange->addItem("100 Ω (RCAL)", 100);
  comboTiaRange->addItem("200 Ω (Internal)", 200);
  comboTiaRange->addItem("1 kΩ (Internal)", 1000);
  // Removed >1k options to prevent saturation
  comboTiaRange->setCurrentIndex(1); // Default 200 (Index 1)

  calibrateBtn = new QPushButton("Calibrate HW", this);
  calibrateBtn->setStyleSheet("background-color: rgba(255, 255, 0, 102); "
                              "color: white; font-weight: bold;");

  // Removed: checkShortRe0Se0

  hwLayout->addWidget(new QLabel("TIA Range:"));
  hwLayout->addWidget(comboTiaRange, 1);
  // Removed: hwLayout->addWidget(checkShortRe0Se0);
  hwLayout->addWidget(calibrateBtn);
  globalLayout->addLayout(hwLayout);

  mainLayout->addWidget(globalGroup);

  // ========================================================================
  // 2. Main Tab Widget (Modes)
  // ========================================================================
  mainTabWidget = new QTabWidget(this);

  // --- Tab 1: Impedance (Sweep & Single) ---
  QWidget *impTab = new QWidget();
  QVBoxLayout *impLayout = new QVBoxLayout(impTab);
  impLayout->setContentsMargins(4, 4, 4, 4);

  // Controls Area
  QGroupBox *impCtrlGroup = new QGroupBox("Impedance Controls", impTab);
  QVBoxLayout *impCtrlLayout = new QVBoxLayout(impCtrlGroup);

  // Sweep Row
  QHBoxLayout *sweepLayout = new QHBoxLayout();
  spinSweepStart = new QDoubleSpinBox();
  spinSweepStart->setRange(0.1, 200000.0);
  spinSweepStart->setValue(1000.0);
  spinSweepStart->setSuffix(" Hz");
  spinSweepStop = new QDoubleSpinBox();
  spinSweepStop->setRange(0.1, 200000.0);
  spinSweepStop->setValue(200000.0);
  spinSweepStop->setSuffix(" Hz");
  spinSweepPPD = new QSpinBox();
  spinSweepPPD->setRange(1, 1000);
  spinSweepPPD->setValue(200);
  spinSweepPPD->setSuffix(" pts/dec");
  sweepBtn = new QPushButton("Sweep");
  sweepBtn->setStyleSheet("background-color: rgba(173, 216, 230, 76); color: "
                          "white; font-weight: bold;");

  sweepLayout->addWidget(new QLabel("Start:"));
  sweepLayout->addWidget(spinSweepStart);
  sweepLayout->addWidget(new QLabel("Stop:"));
  sweepLayout->addWidget(spinSweepStop);
  sweepLayout->addWidget(new QLabel("PPD:"));
  sweepLayout->addWidget(spinSweepPPD);
  sweepLayout->addWidget(sweepBtn);
  impCtrlLayout->addLayout(sweepLayout);

  // Single Freq & Calibration Row
  QHBoxLayout *singleLayout = new QHBoxLayout();
  spinFreq = new QDoubleSpinBox();
  spinFreq->setRange(0.1, 200000.0);
  spinFreq->setValue(1000.0);
  spinFreq->setSuffix(" Hz");

  // New Bias Control
  spinImpBias = new QDoubleSpinBox();
  spinImpBias->setRange(-3000.0, 3000.0);
  spinImpBias->setValue(0.0);
  spinImpBias->setSuffix(" mV");
  spinImpBias->setToolTip("DC Bias Voltage");

  measureBtn = new QPushButton("Measure");
  measureBtn->setStyleSheet("background-color: rgba(0, 100, 0, 76); color: "
                            "white; font-weight: bold;");

  spinCondStd = new QDoubleSpinBox();
  spinCondStd->setRange(0.0, 1000000.0);
  spinCondStd->setValue(1413.0);
  spinCondStd->setSuffix(" µS/cm");
  btnCalCond = new QPushButton("Cal K");
  btnCalCond->setStyleSheet("background-color: rgba(255, 165, 0, 102); color: "
                            "white; font-weight: bold;");

  singleLayout->addWidget(new QLabel("Freq:"));
  singleLayout->addWidget(spinFreq);
  singleLayout->addWidget(new QLabel("Bias:"));
  singleLayout->addWidget(spinImpBias);
  singleLayout->addWidget(measureBtn);
  // Removed Shunt controls
  singleLayout->addWidget(new QLabel("Std:"));
  singleLayout->addWidget(spinCondStd);
  singleLayout->addWidget(btnCalCond);
  impCtrlLayout->addLayout(singleLayout);

  // Results Row
  QHBoxLayout *resLayout = new QHBoxLayout();
  lblResultRs = new QLabel(" Rs: -- Ω");
  lblResultRs->setStyleSheet(
      "font-weight: bold; color: #FFD700; font-size: 14px;");
  lblResultCond = new QLabel("Cond: -- µS/cm");
  lblResultCond->setStyleSheet(
      "font-weight: bold; color: #00FFFF; font-size: 14px;");
  resLayout->addWidget(lblResultRs);
  resLayout->addWidget(lblResultCond);
  resLayout->addStretch();
  impCtrlLayout->addLayout(resLayout);

  impLayout->addWidget(impCtrlGroup);

  // Graphs (Nested Tab)
  impGraphTabs = new QTabWidget();
  rawGraph = new GraphWidget(this);
  rawGraph->configureRawPlot();
  nyquistGraph = new GraphWidget(this);
  nyquistGraph->configureNyquistPlot();

  impGraphTabs->addTab(rawGraph, "Bode Plot");
  impGraphTabs->addTab(nyquistGraph, "Nyquist Plot");
  impLayout->addWidget(impGraphTabs);

  mainTabWidget->addTab(impTab, "Impedance");

  // --- Tab 2: Amperometry ---
  QWidget *ampTab = new QWidget();
  QVBoxLayout *ampLayout = new QVBoxLayout(ampTab);
  ampLayout->setContentsMargins(4, 4, 4, 4);

  QGroupBox *ampCtrlGroup = new QGroupBox("Amperometry Controls", ampTab);
  QHBoxLayout *ampCtrlLayout = new QHBoxLayout(ampCtrlGroup);

  spinAmpBias = new QDoubleSpinBox();
  spinAmpBias->setRange(-3000.0, 3000.0);
  spinAmpBias->setValue(0.0);
  spinAmpBias->setSuffix(" mV");
  comboLPF = new QComboBox();
  comboLPF->addItem("Bypass", 0);
  comboLPF->addItem("20kΩ (8Hz)", 1);
  comboLPF->addItem("100kΩ (1.6Hz)", 2);
  comboLPF->addItem("200kΩ (0.8Hz)", 3);
  comboLPF->addItem("400kΩ (0.4Hz)", 4);
  comboLPF->addItem("600kΩ (0.26Hz)", 5);
  comboLPF->addItem("1MΩ (0.16Hz)", 6);
  comboLPF->setCurrentIndex(1);

  ampBtn = new QPushButton("Start Amp");
  ampBtn->setStyleSheet("background-color: rgba(238, 130, 238, 51); color: "
                        "white; font-weight: bold;");

  ampCtrlLayout->addWidget(new QLabel("Bias:"));
  ampCtrlLayout->addWidget(spinAmpBias);
  ampCtrlLayout->addWidget(new QLabel("LPF:"));
  ampCtrlLayout->addWidget(comboLPF);
  ampCtrlLayout->addWidget(ampBtn);

  ampLayout->addWidget(ampCtrlGroup);

  ampGraph = new GraphWidget(this);
  ampGraph->configureAmperometricPlot();
  ampLayout->addWidget(ampGraph);

  mainTabWidget->addTab(ampTab, "Amperometry");

  // --- Tab 3: Voltammetry (LSV) ---
  QWidget *lsvTab = new QWidget();
  QVBoxLayout *lsvLayout = new QVBoxLayout(lsvTab);
  lsvLayout->setContentsMargins(4, 4, 4, 4);

  QGroupBox *lsvCtrlGroup = new QGroupBox("LSV Controls", lsvTab);
  QHBoxLayout *lsvCtrlLayout = new QHBoxLayout(lsvCtrlGroup);

  spinLsvStart = new QDoubleSpinBox();
  spinLsvStart->setRange(-3000.0, 3000.0);
  spinLsvStart->setValue(800.0);
  spinLsvStart->setSuffix(" mV");
  spinLsvStop = new QDoubleSpinBox();
  spinLsvStop->setRange(-3000.0, 3000.0);
  spinLsvStop->setValue(-200.0);
  spinLsvStop->setSuffix(" mV");
  spinLsvSteps = new QSpinBox();
  spinLsvSteps->setRange(10, 4000);
  spinLsvSteps->setValue(200);
  spinLsvSteps->setSuffix(" pts");
  spinLsvDuration = new QSpinBox();
  spinLsvDuration->setRange(100, 600000);
  spinLsvDuration->setValue(10000);
  spinLsvDuration->setSuffix(" ms");

  lsvBlankBtn = new QPushButton("Run Blank");
  lsvBlankBtn->setStyleSheet(
      "background-color: rgba(0, 0, 0, 255); color: white; font-weight: bold;");
  lsvSampleBtn = new QPushButton("Run Sample");
  lsvSampleBtn->setStyleSheet("background-color: rgba(75, 0, 130, 76); color: "
                              "white; font-weight: bold;");

  lsvCtrlLayout->addWidget(new QLabel("Start:"));
  lsvCtrlLayout->addWidget(spinLsvStart);
  lsvCtrlLayout->addWidget(new QLabel("Stop:"));
  lsvCtrlLayout->addWidget(spinLsvStop);
  lsvCtrlLayout->addWidget(new QLabel("Steps:"));
  lsvCtrlLayout->addWidget(spinLsvSteps);
  lsvCtrlLayout->addWidget(new QLabel("Time:"));
  lsvCtrlLayout->addWidget(spinLsvDuration);
  lsvCtrlLayout->addWidget(lsvBlankBtn);
  lsvCtrlLayout->addWidget(lsvSampleBtn);

  lsvLayout->addWidget(lsvCtrlGroup);

  lsvGraph = new GraphWidget(this);
  lsvGraph->configureLSVPlot();
  lsvLayout->addWidget(lsvGraph);

  mainTabWidget->addTab(lsvTab, "Voltammetry");

  // ========================================================================
  // 3. Log Widget (Bottom)
  // ========================================================================
  logWidget = new QTextEdit(this);
  logWidget->setReadOnly(true);
  logWidget->setFont(QFont("Monospace"));
  logWidget->setPlaceholderText("Scanning for 0xCAFE EIS Device...");
  logWidget->setStyleSheet(
      "background-color: #1E1E1E; color: #00FF00; border: 1px solid #444;");
  logWidget->setMaximumHeight(150);
  QScroller::grabGesture(logWidget->viewport(), QScroller::TouchGesture);

  // Add to Main Layout
  QSplitter *splitter = new QSplitter(Qt::Vertical, this);
  splitter->addWidget(mainTabWidget);
  splitter->addWidget(logWidget);
  splitter->setStretchFactor(0, 4);
  splitter->setStretchFactor(1, 1);

  mainLayout->addWidget(splitter);

  // ========================================================================
  // Initial State & Connections
  // ========================================================================
  checkIdBtn->setEnabled(false);
  calibrateBtn->setEnabled(false);

  comboTiaRange->setEnabled(false);

  // Disable all mode controls initially
  impTab->setEnabled(false);
  ampTab->setEnabled(false);
  lsvTab->setEnabled(false);

  // Connections
  connect(connectBtn, &QPushButton::clicked, this, &MainWindow::connectToPort);
  connect(refreshBtn, &QPushButton::clicked, this, &MainWindow::refreshPorts);
  connect(checkIdBtn, &QPushButton::clicked, this, &MainWindow::checkDeviceId);
  connect(calibrateBtn, &QPushButton::clicked, this,
          &MainWindow::runCalibration);

  connect(sweepBtn, &QPushButton::clicked, this, &MainWindow::startSweep);
  connect(measureBtn, &QPushButton::clicked, this,
          &MainWindow::toggleMeasurement);
  connect(ampBtn, &QPushButton::clicked, this, &MainWindow::toggleAmperometry);
  connect(lsvBlankBtn, &QPushButton::clicked, this, &MainWindow::startLSVBlank);
  connect(lsvSampleBtn, &QPushButton::clicked, this,
          &MainWindow::startLSVSample);
  connect(btnCalCond, &QPushButton::clicked, this,
          &MainWindow::calibrateCellConstant);
  connect(comboLPF, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
          &MainWindow::onLPFChanged);

  connect(mainTabWidget, &QTabWidget::currentChanged, this, [this](int index) {
    if (index == 0)
      rawGraph->configureRawPlot();
    else if (index == 1)
      ampGraph->configureAmperometricPlot();
    else if (index == 2)
      lsvGraph->configureLSVPlot();
  });
}

void MainWindow::setButtonBlinking(QPushButton *btn, bool blinking) {
  if (activeButton && activeButton != btn) {
    // Restore original colors manually based on button type
    if (activeButton == sweepBtn)
      activeButton->setStyleSheet("background-color: rgba(173, 216, 230, 76); "
                                  "color: white; font-weight: bold;");
    else if (activeButton == measureBtn)
      activeButton->setStyleSheet("background-color: rgba(0, 100, 0, 76); "
                                  "color: white; font-weight: bold;");
    else if (activeButton == ampBtn)
      activeButton->setStyleSheet("background-color: rgba(238, 130, 238, 51); "
                                  "color: white; font-weight: bold;");
    else if (activeButton == lsvBlankBtn)
      activeButton->setStyleSheet("background-color: rgba(0, 0, 0, 255); "
                                  "color: white; font-weight: bold;");
    else if (activeButton == lsvSampleBtn)
      activeButton->setStyleSheet("background-color: rgba(75, 0, 130, 76); "
                                  "color: white; font-weight: bold;");
  }

  activeButton = btn;

  if (blinking) {
    blinkTimer->start();
  } else {
    blinkTimer->stop();
    if (activeButton) {
      // Restore original colors manually
      if (activeButton == sweepBtn)
        activeButton->setStyleSheet("background-color: rgba(173, 216, 230, "
                                    "76); color: white; font-weight: bold;");
      else if (activeButton == measureBtn)
        activeButton->setStyleSheet("background-color: rgba(0, 100, 0, 76); "
                                    "color: white; font-weight: bold;");
      else if (activeButton == ampBtn)
        activeButton->setStyleSheet("background-color: rgba(238, 130, 238, "
                                    "51); color: white; font-weight: bold;");
      else if (activeButton == lsvBlankBtn)
        activeButton->setStyleSheet("background-color: rgba(0, 0, 0, 255); "
                                    "color: white; font-weight: bold;");
      else if (activeButton == lsvSampleBtn)
        activeButton->setStyleSheet("background-color: rgba(75, 0, 130, 76); "
                                    "color: white; font-weight: bold;");
    }
    activeButton = nullptr;
  }
}

void MainWindow::onBlinkTimer() {
  if (!activeButton)
    return;

  blinkState = !blinkState;
  if (blinkState) {
    activeButton->setStyleSheet(
        "background-color: #FF0000; color: white; border: 1px solid #FF4444; "
        "font-weight: bold;");
  } else {
    activeButton->setStyleSheet(
        "background-color: #880000; color: white; border: 1px solid #AA0000; "
        "font-weight: bold;");
  }
}