
#include <QFileDialog>
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include "TcpClient.h"

#define DEBUG_HTTP 1

MainWindow::MainWindow(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::MainWindow)
{

    ui->setupUi(this);
    this->statusBar = new QStatusBar();
    this->statusInfo = new QLabel("初始化完成",this);
    this->statusBar->addPermanentWidget(this->statusInfo);//显示正常信息
    QLabel* statusVersion = new QLabel("开启时间:" + QDateTime::currentDateTime().toString("yy.MM.dd.hh.mm"),this);
    this->statusBar->addWidget(statusVersion);

    layout()->addWidget(this->statusBar);

    this->setWindowTitle("Matrix_RFID 车号识别程序(勿关！！)");

    if (!this->mkLogDir())
    {
        this->logError("创建Log目录失败！");
    }

    // 配置文件读取
    QString errorMessage = "";
    if (!ConfigUtil::readBaseConfig(g_config_path, errorMessage, this->baseConfig_))
    {
        this->logError(errorMessage);
    }

    // 获取本机串口列表
    this->getComList();

    // 初始化界面上的串口打开参数
    this->initComboBox();

    m_pSystemTray=new QSystemTrayIcon(this);

    connect(this->ui->openComButton, &QPushButton::clicked, this, &MainWindow::openComClicked);
    connect(this->ui->testButton, &QPushButton::clicked, this, &MainWindow::readTestInfo);

    // 最小化信号槽
    connect(m_pSystemTray,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),this,SLOT(on_activatedSysTrayIcon(QSystemTrayIcon::ActivationReason)));
    //初始最小化
    //this->showMinimized();//最小化
    // 设置最大展示数据行数
    this->ui->textBrowser->document()->setMaximumBlockCount(1000);

    getStandardItemModel();
    this->ui->resultTable->setModel(this->resultTableModel_);
    this->ui->resultTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    this->ui->resultTable->verticalHeader()->setMinimumWidth(50);

//    if (!this->baseConfig_.upResult)
//    {
//        QIcon icon("./Fail.ico");
//        QPixmap m_pic = icon.pixmap(icon.actualSize(QSize(32, 32)));//size自行调整
//        this->ui->upflagLabel->setPixmap(m_pic);
//    }else{
//        QIcon icon("./Succ.ico");
//        QPixmap m_pic = icon.pixmap(icon.actualSize(QSize(32, 32)));//size自行调整
//        this->ui->upflagLabel->setPixmap(m_pic);
//    }

    // 初始化LED指示灯
    this->upResultType(this->baseConfig_.upResult);

    this->readComThread = new ReadComThread(&this->queueTrainInfo_, this);
    this->readComThread->start();

    this->upResultThread = new UpResultThread(&this->queueTrainInfo_, this);
    this->upResultThread->start();

    connect(this, &MainWindow::openCom_signals, this->readComThread, &ReadComThread::openCom);
    connect(this, &MainWindow::readTestRfid_signals, this->readComThread, &ReadComThread::readTestInfo);

    connect(this->readComThread, &ReadComThread::openComSuccess, this, &MainWindow::openComResult);
    connect(this->readComThread, &ReadComThread::closeComSuccess, this, &MainWindow::closeComResult);
    connect(this->readComThread, &ReadComThread::comeTrain, this, &MainWindow::comeTrain);
    connect(this->readComThread, &ReadComThread::upResultType, this, &MainWindow::upResultType);
    // 状态栏信息变化
    connect(this->readComThread, &ReadComThread::statusInfoUpdate, this, &MainWindow::statusInfoUpdate);

    connect(this->readComThread, &ReadComThread::DebugSignals, this, &MainWindow::DebugSlots);
    connect(this->readComThread, &ReadComThread::InfoSignals, this, &MainWindow::InfoSlots);
    connect(this->readComThread, &ReadComThread::WarnSignals, this, &MainWindow::WarnSlots);
    connect(this->readComThread, &ReadComThread::ErrorSignals, this, &MainWindow::ErrorSlots);

    connect(this->upResultThread, &UpResultThread::DebugSignals, this, &MainWindow::DebugSlots);
    connect(this->upResultThread, &UpResultThread::InfoSignals, this, &MainWindow::InfoSlots);
    connect(this->upResultThread, &UpResultThread::WarnSignals, this, &MainWindow::WarnSlots);
    connect(this->upResultThread, &UpResultThread::ErrorSignals, this, &MainWindow::ErrorSlots);

    ui->openComButton->click();
}

MainWindow::~MainWindow()
{
    this->logInfo("-- 程序退出 --");
    delete ui;
}

void MainWindow::logDebug(const QString& message) {
    LogDebug << message.toStdString();
    ui->textBrowser->append(QString("[Debug] [") + this->getSystemTime() + QString::fromStdString("] ") + message);
}
void MainWindow::logInfo(const QString& message) {
    LogInfo << message.toStdString();
    ui->textBrowser->append(QString("[Info] [") + this->getSystemTime() + QString::fromStdString("] ") + message);
}
void MainWindow::logWarn(const QString& message) {
    LogWarn << message.toStdString();
    ui->textBrowser->append(QString("[Warn] [") + this->getSystemTime() + QString::fromStdString("] ") + message);
}
void MainWindow::logError(const QString& message) {
    LogError << message.toStdString();
    ui->textBrowser->append(QString("[Error] [") + this->getSystemTime() + QString::fromStdString("] ") + message);
}
void MainWindow::statusInfoUpdate(const QString &info) {
    this->statusInfo->setText(info);
}

/**
 * 创建日志目录
 * @return bool
 */
bool MainWindow::mkLogDir()
{
    if (_access("Logs", 0) == -1) {				//判断是否存在日志的文件夹，没有则创建
        std::string folderPath = "Logs";
        if (0 != _mkdir(folderPath.c_str()))
        {
            return false;
        }
    }
    return true;
}

/**
 * 获取本地所有串口
 * @return
 */
QList<QString> MainWindow::getComList() {
    // 获取系统所有串口信息
    QList<QSerialPortInfo> availablePorts = QSerialPortInfo::availablePorts();
    for (const auto & availablePort : availablePorts) {
        this->comList.append(availablePort.portName());
    }
    return this->comList;
}

/**
 * 初始化 comboxBox 组件的值
 */
void MainWindow::initComboBox()
{
//    ui->BTBox->setEditable(true);
    ui->BTBox->setStyleSheet("QComboBox {background-color: rgb(255, 255, 255);} QComboBox QAbstractItemView::item {min-height: 30px; background-color: rgb(255, 255, 255); color: rgb(225, 225, 225);}");
    ui->BTBox->setView(new QListView());
    ui->comBox->setEditable(true);
    ui->comBox->setStyleSheet("QComboBox {background-color: rgb(255, 255, 255);} QComboBox QAbstractItemView::item {min-height: 30px; background-color: rgb(255, 255, 255); color: rgb(225, 225, 225);}");
    ui->comBox->setMaxVisibleItems(5);
    ui->comBox->setView(new QListView());
    ui->comBox->addItems(this->comList);
    if (this->baseConfig_.comName != "") {
        if (ui->comBox->findText(this->baseConfig_.comName) == -1)
        {
            ui->comBox->addItem(this->baseConfig_.comName);
        }
        ui->comBox->setCurrentText(this->baseConfig_.comName);
    }
    if (ui->BTBox->findText(QString::number(this->baseConfig_.baud)) == -1)
    {
        ui->BTBox->addItem(QString::number(this->baseConfig_.baud));
    }
    ui->BTBox->setCurrentText(QString::number(this->baseConfig_.baud));

    ui->truckEdit->setText(QString::number(this->baseConfig_.trackName));
}

/**
 * @brief:获取系统时间
 * @param：
 * @return:空
 */
QString MainWindow::getSystemTime()
{
    return QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
}

/**
 * 获取结果框的ItemModel
 * @return
 */
QStandardItemModel* MainWindow::getStandardItemModel()
{
    if (this->resultTableModel_== nullptr) this->resultTableModel_ = new QStandardItemModel();
    this->resultTableModel_->setColumnCount(1);
    this->resultTableModel_->setHeaderData(0,Qt::Horizontal, "车号");
    return this->resultTableModel_;
}

QStandardItem* MainWindow::getStandardItem(const QString &value)
{
    QStandardItem *resultTableItem = new QStandardItem();
    resultTableItem->setTextAlignment(Qt::AlignCenter);
    resultTableItem->setText(value);
    return resultTableItem;
}

/***************************最小化相关****************************************/
/**
 * @brief:接收最小化信号
 * @param：
 * @return:空
 */
void MainWindow::changeEvent(QEvent *event)
{
    if((event->type()==QEvent::WindowStateChange)&&isMinimized())
    {
        this->hide();
        m_pSystemTray->setIcon(QIcon("./logo.ico"));     // 托盘时显示的图片
        m_pSystemTray->setToolTip("Rfid车号识别-股道号:" + QString::number(this->baseConfig_.trackName));                                             // 鼠标在托盘图片时的提示
        m_pSystemTray->showMessage("Rfid车号识别","已隐藏至托盘",QSystemTrayIcon::Information,10000);
        event->ignore();
        //建立托盘操作的菜单
        creat_action();
        creat_menu();
        m_pSystemTray->show();   // 显示图片图标
    }
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    // 弹出对话框要求用户输入账号和密码
    QString password = QInputDialog::getText(this, "密码验证", "请输入密码：", QLineEdit::Password);

    // 验证账号和密码是否正确
    if (password == "matrix") {
        event->accept();  // 关闭窗口
        exit(0);
    } else {
        QMessageBox::warning(this, "验证失败", "密码不正确！");
        event->ignore();  // 阻止关闭窗口
    }
}

void MainWindow::creat_action()
{
    m_pActionShow = new QAction("主界面", this);
    connect(m_pActionShow, &QAction::triggered, this,&MainWindow::on_ShowMainAction);
//    m_pActionQuit = new QAction("退出", this);
//    connect(m_pActionQuit, &QAction::triggered, this, &MainWindow::on_ExitAppAction);
}

void MainWindow::creat_menu()
{
    m_pTrayMennu = new QMenu(this);
    //新增菜单项---显示主界面
    m_pTrayMennu->addAction(m_pActionShow);
    //增加分隔符
//    m_pTrayMennu->addSeparator();
//    //新增菜单项---退出程序
//    m_pTrayMennu->addAction(m_pActionQuit);
    //把QMenu赋给QSystemTrayIcon对象
    m_pSystemTray->setContextMenu(m_pTrayMennu);
}

/**
* @brief:显示
* @param：
* @return:空
*/
void MainWindow::on_ShowMainAction()
{
    this->show();
    this->showNormal();
    this->activateWindow();
}

void MainWindow::on_activatedSysTrayIcon(QSystemTrayIcon::ActivationReason reason)
{
    switch(reason){
        case QSystemTrayIcon::Trigger:
            //单击托盘图标
            this->showNormal();
            break;
        case QSystemTrayIcon::DoubleClick:
            //双击托盘图标
            //双击后显示主程序窗口
            this->showNormal();
            this->activateWindow();
            break;
        default:
            break;
    }
}

/********************************串口操作*************************************/
/**
 * 打开串口
 */
void MainWindow::openComClicked()
{
    if (ui->openComButton->text() == "打开串口")
    {
        this->auto_reconnect_serial_ = true;
        emit openCom_signals(true);
    }
    else
    {
        // 弹出对话框要求用户输入密码
        QString password = QInputDialog::getText(this, "密码验证", "请输入密码：", QLineEdit::Password);

        // 验证账号和密码是否正确
        if (password == "matrix") {
            this->auto_reconnect_serial_ = false;

            emit openCom_signals(false);
        } else {
            QMessageBox::warning(this, "验证失败", "密码不正确！");
        }
    }
}

void MainWindow::openComResult(const bool &success)
{
    this->ui->openComButton->setText("关闭串口");
    if (success)
    {
        this->ui->LEDlabel->setStyleSheet("border-radius: 16px;\ "
                                          "background-color: rgba(74, 221, 108, 225);\ "
                                          "border:1px solid rgba(168, 168, 168, 105);");
    }
    else
    {
        this->ui->LEDlabel->setStyleSheet("border-radius: 16px;\ "
                                          "background-color: red;\ "
                                          "border:1px solid rgba(168, 168, 168, 105);");

        this->logInfo("10秒钟后自动尝试重连串口...");
//        if (auto_reconnect_serial_) emit openCom_signals(true, 10 * 1000);
    }
}

void MainWindow::closeComResult(const bool &success)
{
    if (success)
    {
        this->ui->openComButton->setText("打开串口");
        this->ui->LEDlabel->setStyleSheet("border-radius: 16px;\ "
                                          "background-color: red;\ "
                                          "border:1px solid rgba(168, 168, 168, 105);");
    }
    else
    {
        this->ui->LEDlabel->setStyleSheet("border-radius: 16px;\ "
                                          "background-color: rgba(74, 221, 108, 225);\ "
                                          "border:1px solid rgba(168, 168, 168, 105);");
    }
}

void MainWindow::comeTrain(const bool &success) {
    this->resultTableModel_->clear();
    this->resultTableModel_ = this->getStandardItemModel();
}

void MainWindow::upResultType(const bool &type) {
    if (type) {
        QIcon icon("./Succ.ico");
        QPixmap m_pic = icon.pixmap(icon.actualSize(QSize(32, 32)));//size自行调整
        this->ui->upflagLabel->setPixmap(m_pic);
    } else {
        QIcon icon("./Fail.ico");
        QPixmap m_pic = icon.pixmap(icon.actualSize(QSize(32, 32)));//size自行调整
        this->ui->upflagLabel->setPixmap(m_pic);
    }
}

void MainWindow::DebugSlots(const QString &info) {
    this->logDebug(info);
}

void MainWindow::InfoSlots(const QString &info) {
    this->logInfo(info);
}

void MainWindow::WarnSlots(const QString &info) {
    this->logWarn(info);
}

void MainWindow::ErrorSlots(const QString &info) {
    this->logError(info);
}

// ============================= 测试 ====================================

void MainWindow::readTestInfo()
{
    if (this->ui->openComButton->text() == "关闭串口")
    {
        logWarn("请先关闭串口后进行测试操作！");
        return;
    }
    QString filePath = QFileDialog::getOpenFileName(this, "选择一个文件", QDir::currentPath(), "(*.*)");
    if(filePath.isEmpty()){
//        QMessageBox::warning(this, "打开文件", "选择文件不能为空");
        return;
    }

    emit this->readTestRfid_signals(filePath);
}