#include "PhaseWindow.h"
#include "ui_PhaseWindow.h"

#include <iostream>
#include <QTimer>
#include <QDateTime>
#include <QLabel>
#include <QGroupBox>
#include <QLineEdit>
#include <QPushButton>
#include <QHBoxLayout>
#include <QDesktopWidget>
#include <QThread>

PhaseWindow::PhaseWindow(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::PhaseWindow)
{
    ui->setupUi(this);

    // 无边框
    this->setWindowFlags(Qt::FramelessWindowHint);

    // 窗口大小为占满一屏
    QRect screenRect = QApplication::desktop()->availableGeometry();
    resize(screenRect.width(), screenRect.height());

    // 将窗口移动到左上角
    move(0, 0);
    ui->exitButt->move(screenRect.width() - 80, 10);
    ui->minButt->move(screenRect.width() - 140, 10);
    ui->endButt->move(screenRect.width() - 200, 10);
    ui->startButt->move(screenRect.width() - 260, 10);
    ui->line->setGeometry(0, 59, screenRect.width(), 1);

    // 设置主体区域的大小和位置
    ui->scrollArea->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60);
    ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);

    ui->logo->setText(QString("相位测量数据采集软件——%1").arg(SettingConfig::getInstance().MASTER == 1 ? "主" : "备"));

    httpReq = new HttpRequestController(this);
    // 1. 获取访问接口需要的token
    int retCode = this->initHttpToken();
    if (retCode != 200)
    {
        QMessageBox::information(this, "错误", "获取http请求的token失败，程序即将退出");

        QTimer::singleShot(1000, qApp, SLOT(quit()));
    }
    // 2. 获取字典值：设备类型
    retCode = this->initDictDeviceTypes();

    // 3. 获取比相仪设备列表
    QJsonObject devListRes = this->initDeviceList();
    if (devListRes.find("code")->toInt() == 200)
    {
        ui->devSelect->clear();

        // 4. 将获取到的设备添加到下拉列表框中
        QJsonArray devArray = devListRes.find("data")->toArray();
        for (int i = 0; i < devArray.size(); i++)
        {
            QJsonObject devItem = devArray.at(i).toObject();
            ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem.find("deviceNo")->toString());

            PhaseDevice * device = new PhaseDevice(this);
            deviceList.append(device);

            device->setComName(devItem.find("linkComName")->toString());
            device->setBaudRate(SettingConfig::getInstance().BAUD_RATE);
            device->setDevCode(devItem.find("deviceNo")->toString());
            device->setDeviceId(devItem.find("deviceId")->toString());

            connect(device, &PhaseDevice::sendDataToDraw, this, &PhaseWindow::drawPhaseDataOnPage);
            connect(device, &PhaseDevice::sendAllenToDraw, this, &PhaseWindow::drawPhaseAllenOnPage);

            device->initSerialPort();

            QThread::msleep(100);
            device->startWork();
        }
        // 5. 设置下拉框的样式
        QStandardItemModel * model = qobject_cast<QStandardItemModel*>(ui->devSelect->model());
        for (int i = 0; i < model->rowCount(); ++i)
        {
            QStandardItem * item = model->item(i);
            item->setSizeHint({ 0, 30 });
        }
    }

    // 6. 绘制一个设备的多个通道数据面板
    this->generateWidgetForDevice();

    HttpServer::instance().run(QHostAddress::Any, SettingConfig::getInstance().SERVER_PORT);
}

PhaseWindow::~PhaseWindow()
{
    delete ui;
}

void PhaseWindow::drawPhaseDataOnPage(PhaseDataDto * phaseData)
{
    // 当前显示的设备编号
    QString currentDevCode = ui->devSelect->currentData().toString();

    // 如果不是当前设备的帧，直接返回
    if (phaseData->devCode != currentDevCode)
    {
        return;
    }

    ui->labTm->setText(phaseData->timestamp.left(19));

    // 更新所有通道BOX的值
    for (int i = 0; i < phaseData->channelActive.size(); i++)
    {
        // 获取对应的通道BOX
        QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1);

        // 赋值，对应的lineEdit/label
        ((QLabel *)channelBox->children().at(1))->setText(phaseData->channelActive.at(i) == "1" ? "有效" : "无效"); // 有效性
        ((QLabel *)channelBox->children().at(2))->setText(phaseData->frameId); // 数据ID
        ((QLineEdit *)channelBox->children().at(4))->setText(QString("%1 s").arg(phaseData->channelDataStr.at(i))); // 测量数据值
    }
}

void PhaseWindow::drawPhaseAllenOnPage(QString devCode, QVector<QStringList> channelAllenResultStr)
{
    // 当前显示的设备编号
    QString currentDevCode = ui->devSelect->currentData().toString();

    // 如果不是当前设备的帧，直接返回
    if (devCode != currentDevCode)
    {
        return;
    }

    // 更新所有通道BOX的值
    for (int i = 0; i < channelAllenResultStr.size(); i++)
    {
        // 获取对应的通道BOX
        QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1);

        // 赋值，对应的label
        ((QLabel *)channelBox->children().at(7))->setText(channelAllenResultStr.at(i).at(0)); // tau=1 Allen
        ((QLabel *)channelBox->children().at(8))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(1))); // tau=1 Count

        ((QLabel *)channelBox->children().at(10))->setText(channelAllenResultStr.at(i).at(2)); // tau=10 Allen
        ((QLabel *)channelBox->children().at(11))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(3))); // tau=10 Count

        ((QLabel *)channelBox->children().at(13))->setText(channelAllenResultStr.at(i).at(4)); // tau=100 Allen
        ((QLabel *)channelBox->children().at(14))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(5))); // tau=100 Count

        ((QLabel *)channelBox->children().at(16))->setText(channelAllenResultStr.at(i).at(6)); // tau=1000 Allen
        ((QLabel *)channelBox->children().at(17))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(7))); // tau=1000 Count

        ((QLabel *)channelBox->children().at(19))->setText(channelAllenResultStr.at(i).at(8)); // tau=10000 Allen
        ((QLabel *)channelBox->children().at(20))->setText(QString("采样数(%1)").arg(channelAllenResultStr.at(i).at(9))); // tau=10000 Count
    }

//    qDebug() << channelAllenResultStr;
}

void PhaseWindow::generateWidgetForDevice()
{
    // 获取设备数据
    int channelNum = 16;

    QRect screenRect = QApplication::desktop()->screenGeometry();

    ui->scrollContents->setGeometry(0, 60, screenRect.width(), channelNum * 90);

    QVBoxLayout * layout = new QVBoxLayout(ui->scrollContents);
    const QFont labelFont("微软雅黑", 10);

    for (int i = 0; i < channelNum; i++)
    {
        QGroupBox * group = new QGroupBox(ui->scrollContents);
        group->setTitle(QString("通道 - %1").arg(i + 1));
        group->setFont(QFont("微软雅黑", 12));
        group->setGeometry(20, i * 80 + 10, screenRect.width() - 40, 80);

        QHBoxLayout * vbox = new QHBoxLayout(group);

        // index = 1
        QLabel * validLabel = new QLabel();
        validLabel->setText("-");
        validLabel->setFont(labelFont);
        validLabel->setStyleSheet("margin-left:20;");
        vbox->addWidget(validLabel);

        // index = 2
        QLabel * idLabel = new QLabel();
        idLabel->setText("0000");
        idLabel->setFont(labelFont);
        idLabel->setStyleSheet("margin-left:20;");
        vbox->addWidget(idLabel);

        // index = 3
        QLabel * dataLabel = new QLabel();
        dataLabel->setText("测量数据");
        dataLabel->setFont(labelFont);
        dataLabel->setStyleSheet("margin-left:20;");
        vbox->addWidget(dataLabel);
        // index = 4
        QLineEdit * dataValue = new QLineEdit();
        dataValue->setFixedWidth(200);
        dataValue->setFont(labelFont);
        vbox->addWidget(dataValue);

        // index = 5
        QLabel * perfLabel = new QLabel();
        perfLabel->setText("稳定度");
        perfLabel->setFont(labelFont);
        perfLabel->setStyleSheet("margin-left:50;");
        vbox->addWidget(perfLabel);

        // index = 6
        QLabel * oneLabel = new QLabel();
        oneLabel->setText("Tau(s)=1");
        oneLabel->setFont(labelFont);
        oneLabel->setStyleSheet("margin-left:20;");
        vbox->addWidget(oneLabel);
        // index = 7
        QLabel * oneAllen = new QLabel();
        oneAllen->setText("0.00");
        oneAllen->setFont(labelFont);
        vbox->addWidget(oneAllen);
        // index = 8
        QLabel * oneCount = new QLabel();
        oneCount->setText("0");
        oneCount->setFont(labelFont);
        vbox->addWidget(oneCount);

        // index = 9
        QLabel * tenLabel = new QLabel();
        tenLabel->setText("Tau(s)=10");
        tenLabel->setFont(labelFont);
        tenLabel->setStyleSheet("margin-left:20;");
        vbox->addWidget(tenLabel);
        // index = 10
        QLabel * tenAllen = new QLabel();
        tenAllen->setText("0.00");
        tenAllen->setFont(labelFont);
        vbox->addWidget(tenAllen);
        // index = 11
        QLabel * tenCount = new QLabel();
        tenCount->setText("0");
        tenCount->setFont(labelFont);
        vbox->addWidget(tenCount);

        // index = 12
        QLabel * hundLabel = new QLabel();
        hundLabel->setText("Tau(s)=100");
        hundLabel->setFont(labelFont);
        hundLabel->setStyleSheet("margin-left:20;");
        vbox->addWidget(hundLabel);
        // index = 13
        QLabel * hundAllen = new QLabel();
        hundAllen->setText("0.00");
        hundAllen->setFont(labelFont);
        vbox->addWidget(hundAllen);
        // index = 14
        QLabel * hundCount = new QLabel();
        hundCount->setText("0");
        hundCount->setFont(labelFont);
        vbox->addWidget(hundCount);

        // index = 15
        QLabel * thouLabel = new QLabel();
        thouLabel->setText("Tau(s)=1000");
        thouLabel->setFont(labelFont);
        thouLabel->setStyleSheet("margin-left:20;");
        vbox->addWidget(thouLabel);
        // index = 16
        QLabel * thouAllen = new QLabel();
        thouAllen->setText("0.00");
        thouAllen->setFont(labelFont);
        vbox->addWidget(thouAllen);
        // index = 17
        QLabel * thouCount = new QLabel();
        thouCount->setText("0");
        thouCount->setFont(labelFont);
        vbox->addWidget(thouCount);

        // index = 18
        QLabel * ttLabel = new QLabel();
        ttLabel->setText("Tau(s)=10000");
        ttLabel->setFont(labelFont);
        ttLabel->setStyleSheet("margin-left:20;");
        vbox->addWidget(ttLabel);
        // index = 19
        QLabel * ttAllen = new QLabel();
        ttAllen->setText("0.00");
        ttAllen->setFont(labelFont);
        vbox->addWidget(ttAllen);
        // index = 20
        QLabel * ttCount = new QLabel();
        ttCount->setText("0");
        ttCount->setFont(labelFont);
        vbox->addWidget(ttCount);

        QSpacerItem * hSpace = new QSpacerItem(20, 20);
        hSpace->changeSize(20, 20, QSizePolicy::Expanding);
        vbox->addItem(hSpace);

        group->setLayout(vbox);

        layout->addWidget(group);
    }
}

int PhaseWindow::initHttpToken()
{
    QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID,
                                                       SettingConfig::getInstance().APP_KEY);
    return response.find("code")->toInt();
}
int PhaseWindow::initDictDeviceTypes()
{
    QJsonObject response = httpReq->initDictDeviceType();
    return response.find("code")->toInt();
}
QJsonObject PhaseWindow::initDeviceList()
{
    QJsonObject response = httpReq->initDeviceList(SettingConfig::getInstance().DEV_TYPES, SettingConfig::getInstance().SYSTEM);
    return response;
}

void PhaseWindow::on_minButt_clicked()
{
    setWindowState(Qt::WindowMinimized | windowState());
}

void PhaseWindow::on_exitButt_clicked()
{
    QApplication::exit(0);
}

void PhaseWindow::on_startButt_clicked()
{
    int devSelected = ui->devSelect->currentIndex();
    PhaseDevice * device = deviceList.at(devSelected);
    device->startWork();
}

void PhaseWindow::on_endButt_clicked()
{
    int devSelected = ui->devSelect->currentIndex();
    PhaseDevice * device = deviceList.at(devSelected);
    device->stopWork();
}

void PhaseWindow::on_devSelect_currentIndexChanged(int index)
{
    // 清空显示的数据
    if (ui->scrollContents->children().size() < 1)
    {
        return ;
    }

    for (int i = 0; i < 16; i++)
    {
        // 获取对应的通道BOX
        QGroupBox * channelBox = (QGroupBox *)ui->scrollContents->children().at(i + 1);

        // 赋值，对应的lineEdit/label
        ((QLabel *)channelBox->children().at(1))->setText("-"); // 有效性
        ((QLabel *)channelBox->children().at(2))->setText("0000"); // 数据ID
        ((QLineEdit *)channelBox->children().at(4))->setText(""); // 测量数据值

        ((QLabel *)channelBox->children().at(7))->setText("0.00"); // tau=1 Allen
        ((QLabel *)channelBox->children().at(8))->setText(QString("采样数(%1)").arg(0)); // tau=1 Count

        ((QLabel *)channelBox->children().at(10))->setText("0.00"); // tau=10 Allen
        ((QLabel *)channelBox->children().at(11))->setText(QString("采样数(%1)").arg(0)); // tau=10 Count

        ((QLabel *)channelBox->children().at(13))->setText("0.00"); // tau=100 Allen
        ((QLabel *)channelBox->children().at(14))->setText(QString("采样数(%1)").arg(0)); // tau=100 Count

        ((QLabel *)channelBox->children().at(16))->setText("0.00"); // tau=1000 Allen
        ((QLabel *)channelBox->children().at(17))->setText(QString("采样数(%1)").arg(0)); // tau=1000 Count

        ((QLabel *)channelBox->children().at(19))->setText("0.00"); // tau=10000 Allen
        ((QLabel *)channelBox->children().at(20))->setText(QString("采样数(%1)").arg(0)); // tau=10000 Count
    }
}
