#include "DeviceHubWindow.h"
#include "ui_DeviceHubWindow.h"

#include <QTimer>
#include <QMessageBox>
#include <QDesktopWidget>
#include <QStandardItemModel>

DeviceHubWindow::DeviceHubWindow(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::DeviceHubWindow)
{
    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->line->setGeometry(0, 59, screenRect.width(), 1);

    // 设置stackWidget的大小
    ui->stackedWidget->setGeometry(0, 60, screenRect.width(), screenRect.height() - 60);

    // 添加设备状态Form
    QStringList devTypes = SettingConfig::getInstance().DEV_TYPES.split(",");
    for (int i = 0; i < devTypes.size(); i++)
    {
        this->initDeviceForm(devTypes.at(i));
    }

    // kafka consumer
    kafkaConsumer = new QKafkaConsumer(this);
    kafkaConsumer->setBrokers(SettingConfig::getInstance().KAFKA_BROKERS);
    kafkaConsumer->setTopic(SettingConfig::getInstance().KAFKA_CMD_TOPIC);
    kafkaConsumer->createConsumer();
    kafkaConsumer->start();

    // init device type and device list
    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();
    this->initAllDeviceList();

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

DeviceHubWindow::~DeviceHubWindow()
{
    kafkaConsumer->exitThread();
    kafkaConsumer->deleteLater();
    kafkaConsumer->wait();

    delete ui;

    delete kafkaConsumer;
}

QComboBox * DeviceHubWindow::getDevTypeSelect()
{
    return ui->devTypeSelect;
}
QComboBox * DeviceHubWindow::getDevSelect()
{
    return ui->devSelect;
}

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

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

void DeviceHubWindow::on_devTypeSelect_currentIndexChanged(int index)
{
    ui->stackedWidget->setCurrentIndex(index);
    currentDevType = ui->devTypeSelect->currentData().toString();

    //
    QList<QJsonObject> typeDevList = ConstCache::getInstance().deviceList.value(currentDevType);
    ui->devSelect->clear();
    for (int var = 0; var < typeDevList.size(); ++var) {
        QJsonObject devItem = typeDevList.at(var);
        ui->devSelect->addItem(devItem.find("deviceName")->toString(), devItem);
    }

    // 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 });
    }
}

void DeviceHubWindow::on_devSelect_currentIndexChanged(int index)
{
    currentDevIndex = index;
}

int DeviceHubWindow::initHttpToken()
{
    QJsonObject response = httpReq->getTokenByClientId(SettingConfig::getInstance().CLIENT_ID,
                                                       SettingConfig::getInstance().APP_KEY);

    return response.find("code")->toInt();
}

int DeviceHubWindow::initDictDeviceTypes()
{
    QJsonObject response = httpReq->initDictDeviceType();

    if (response.find("code")->toInt() == 200)
    {
        ConstCache::getInstance().deviceTypes.clear();

        QJsonArray typeArray = response.find("data")->toArray();
        for (int i = 0; i < typeArray.size(); i++)
        {
            QJsonObject typeItem = typeArray.at(i).toObject();
            if (SettingConfig::getInstance().DEV_TYPES.contains(typeItem.find("value")->toString()) == true)
            {
                ui->devTypeSelect->addItem(typeItem.find("name")->toString(), typeItem.find("value")->toString());
                ConstCache::getInstance().deviceTypes.insert(typeItem.find("value")->toString(), typeItem.find("name")->toString());
            }
        }
    }

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

    // 默认选中第一个设备类型
//    ui->devTypeSelect->setCurrentIndex(model->rowCount() - 1);

    return response.find("code")->toInt();
}

void DeviceHubWindow::initAllDeviceList()
{
    QStringList sysList = SettingConfig::getInstance().SYSTEM.split(",");
    QStringList devTypes = SettingConfig::getInstance().DEV_TYPES.split(",");
    for (int i = 0; i < devTypes.size(); i++)
    {
        QString devType = devTypes.at(i);
        QList<QJsonObject> typeDevList;
        QList<DeviceBase *> singleTypeDevList;
        for (int j = 0; j < sysList.size(); j++)
        {
            QJsonObject resultObj = httpReq->initDeviceList(devType, sysList.at(j));
            if (resultObj.find("code")->toInt() == 200)
            {
                QJsonArray data = resultObj.find("data")->toArray();
                for (int ii = 0; ii < data.size(); ii++)
                {
                    QJsonObject item = data.at(ii).toObject();
                    typeDevList.append(item);
                    qDebug() << item;

                    DeviceBase * devicePtr = DeviceBase::deviceFactory(devType, this);
                    if (devicePtr != 0)
                    {
                        devicePtr->setDevCode(item.find("deviceNo")->toString());
                        devicePtr->setDeviceId(item.find("deviceId")->toString());
                        devicePtr->setComName(item.find("linkComName")->toString());
                        devicePtr->setBaudRate(item.find("baudRate")->toString().toInt());

                        singleTypeDevList.append(devicePtr);

                        // 如果是真实工作模式则打开串口连接
                        if (SettingConfig::getInstance().WORK_MODE == "real")
                        {
                            devicePtr->initSerialPort();
                        }
                    }
                }
            }
        }

        this->allTypeDevList.insert(devType, singleTypeDevList);
        ConstCache::getInstance().deviceList.insert(devType, typeDevList);
    }

    if (ui->devTypeSelect->currentIndex() == 0)
    {
        this->on_devTypeSelect_currentIndexChanged(0);
    } else {
        ui->devTypeSelect->setCurrentIndex(0);
    }
}

void DeviceHubWindow::initDeviceForm(QString devType)
{
    if (devType == "03")
    {
        freqTunForm = new FrequencyTuningForm(this);
        ui->stackedWidget->addWidget(freqTunForm);
    }

    if (devType == "04")
    {
        signGenForm = new SignalGeneratorForm(this);
        ui->stackedWidget->addWidget(signGenForm);
    }

    if (devType == "05")
    {
        tmSwitForm = new TimeSwitcherForm(this);
        ui->stackedWidget->addWidget(tmSwitForm);
    }

    if (devType == "06")
    {
        freqSwitForm = new FreqSwitcherForm(this);
        ui->stackedWidget->addWidget(freqSwitForm);
    }

    if (devType == "07")
    {
        bCodeTermForm = new BCodeTerminalForm(this);
        ui->stackedWidget->addWidget(bCodeTermForm);
    }

    if (devType == "09")
    {
        timeRepForm = new TimeReplicatorForm(this);
        ui->stackedWidget->addWidget(timeRepForm);
    }

    if (devType == "10")
    {
        freqRepForm = new FreqReplicatorForm(this);
        ui->stackedWidget->addWidget(freqRepForm);
    }

    if (devType == "11")
    {
        ntpServForm = new NtpServerForm(this);
        ui->stackedWidget->addWidget(ntpServForm);
    }
}
