#include "blastopepage.h"

#include <QFont>
#include <QProcessEnvironment>
#include <QWebEngineSettings>

#include "countdownwidget.h"
#include "global.h"
#include "loadingwidget.h"
#include "logger.h"
#include "loginwindow.h"
#include "registryManager/registrymanager.h"
#include "ui_blastopepage.h"

BlastOpePage::BlastOpePage(QWidget *parent)
    : QWidget(parent), ui(new Ui::BlastOpePage), dao(DatabaseManager::getInstance().getDatabase()) {
    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
    // InitFace();
    ui->setupUi(this);
    initPagination();
}

void BlastOpePage::showDownWidget(QString uuid, const QString &topic, const QString &message) {
    CountdownWidget *countdownWidget = new CountdownWidget(this);
    countdownWidget->resize(200, 200);
    int x = (this->width() - countdownWidget->width()) / 2;
    int y = (this->height() - countdownWidget->height()) / 2;

    countdownWidget->move(x, y);
    countdownWidget->show();
    firingWidget *widget = uuidWidgetMap.value(uuid);

    if (widget) {
        connect(
            countdownWidget, &CountdownWidget::countdownFinished, widget,
            [widget, topic, message, countdownWidget]() {
                widget->onCountdownFinished(topic, message);
            },
            Qt::SingleShotConnection);
    }
}

void BlastOpePage::InitFace() {
    Logger::getInstance().info("start init face verification");
    LoadingWidget::showLoading(this, "请求创建人脸识别...");

    layout = new QVBoxLayout(this);
    // TODO: relase the qwebengineview when not successfully verified
    view = new QWebEngineView(this);
    view->setAttribute(Qt::WA_OpaquePaintEvent);

    QWebEnginePage *page = view->page();

    QJsonObject metaInfo = getMetaInfo();
    if (metaInfo["certName"] == "" || metaInfo["certNo"] == "") {
        QMessageBox::information(nullptr, "获取用户信息错误",
                                 "未获得用户的身份证信息,请联系管理员");
        return;
    }

    QObject::connect(page, &QWebEnginePage::featurePermissionRequested,
                     [this, page](const QUrl &securityOrigin, QWebEnginePage::Feature feature) {
                         handleFeaturePermission(page, securityOrigin, feature);
                     });

    Logger::getInstance().info("FaceVerification: connect");
    QUrl postUrl(apiBackendUrl.resolved(QUrl("h-face-verify/pc")));
    QJsonObject response = sendPostRequest(postUrl, metaInfo);
    QString certifyUrl;
    if (response["code"] != 200) {
        Logger::getInstance().error(
            QString("创建人脸识别请求服务器返回错误: userName: %1. response: %2")
                .arg(metaInfo["certName"].toString(),
                     QString::fromUtf8(QJsonDocument(response).toJson())));
        QMessageBox::critical(nullptr, "错误", "无法创建人脸识别，请确认后台录入的身份信息正确");
        return;
    }
    if (response.contains("data") && response["data"].isObject()) {
        LoadingWidget::showLoading(this, "正在打开人脸识别界面...");
        QJsonObject dataObject = response["data"].toObject();
        if (dataObject.contains("ResultObject") && dataObject["ResultObject"].isObject()) {
            QJsonObject resultObject = dataObject["ResultObject"].toObject();
            if (resultObject.contains("CertifyId") && resultObject["CertifyId"].isString()) {
                certifyId = resultObject["CertifyId"].toString();
            }
            if (resultObject.contains("CertifyUrl") && resultObject["CertifyUrl"].isString()) {
                certifyUrl = resultObject["CertifyUrl"].toString();
            }
        }
    }
    if (!certifyUrl.isEmpty()) {
        view->load(QUrl(certifyUrl));

        layout->addWidget(view);

        layout->setStretchFactor(view, 1);

        QObject::connect(page, &QWebEnginePage::urlChanged, this, &BlastOpePage::onUrlChanged);
    } else {
        QMessageBox::information(nullptr, "提示", "人脸识别请求失败");
        Logger::getInstance().error("FaceVerificationInit: Failed to get certifyUrl");
    }
    Logger::getInstance().info("FaceVerificationInit: successfully");
    LoadingWidget::hideLoading();
}

void BlastOpePage::closeWebViewAndRestoreUI() {
    if (view) {
        layout->removeWidget(view);
        delete view;
        view = nullptr;
    }
    if (layout) {
        delete layout;
        layout = nullptr;
    }
}

// 槽函数：处理 URL 改变事件
void BlastOpePage::onUrlChanged(const QUrl &newUrl) {
    LoadingWidget::showLoading(this, "查询验证结果...");
    if (newUrl.host() == "www.integrateblaster.com") {
        closeWebViewAndRestoreUI();
        QNetworkAccessManager manager;
        QUrl requestUrl(
            apiBackendUrl.resolved(QUrl(QString("h-face-verify/certifyId/%1").arg(certifyId))));
        QNetworkRequest request(requestUrl);
        QNetworkReply *reply = manager.get(request);
        QEventLoop loop;
        QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
        loop.exec();

        if (reply->error() == QNetworkReply::NoError) {
            QByteArray responseData = reply->readAll();
            QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData);
            if (!jsonDoc.isNull() && jsonDoc.isObject()) {
                QJsonObject rootObj = jsonDoc.object();
                QJsonObject dataObj = rootObj["data"].toObject();
                QString message = dataObj["Message"].toString();
                QJsonObject resultObj = dataObj["ResultObject"].toObject();
                if (resultObj.isEmpty()) {
                    Logger::getInstance().error(
                        QString("获取认证初始化数据失败. message: %1.").arg(message));
                    int ret =
                        QMessageBox::information(nullptr, "认证失败", message + " ,请重新认证！");
                    if (ret == QMessageBox::Ok) {
                        InitFace();
                    }
                } else {
                    QString passed = resultObj["Passed"].toString();
                    if (passed == "T") {
                        ui->setupUi(this);
                        initPagination();
                        Logger::getInstance().info(QString("进入认证界面"));
                        LoadingWidget::hideLoading();
                    } else if (passed == "F") {
                        int ret = QMessageBox::critical(nullptr, "提示", "操作失败，请重新认证！");
                        if (ret == QMessageBox::Ok) {
                            InitFace();
                        }
                    }
                }
            }
        } else {
            qDebug() << "Request failed:" << reply->errorString();
            Logger::getInstance().error(
                QString("InitFaseVerification request failed. error message: %1")
                    .arg(reply->errorString()));
        }

        reply->deleteLater();
        LoadingWidget::hideLoading();
    }
    LoadingWidget::hideLoading();
}

BlastOpePage::~BlastOpePage() {
    delete ui;

    if (view) {
        delete view;
    }
    if (layout) {
        delete layout;
    }
}

QJsonObject BlastOpePage::sendPostRequest(const QUrl &url, const QJsonObject &data) {
    QNetworkAccessManager manager;
    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    QJsonDocument doc(data);
    QByteArray postData = doc.toJson();

    QNetworkReply *reply = manager.post(request, postData);

    QEventLoop loop;
    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();

    QJsonObject responseJson;
    if (reply->error() == QNetworkReply::NoError) {
        QByteArray responseData = reply->readAll();
        QJsonDocument responseDoc = QJsonDocument::fromJson(responseData);
        if (!responseDoc.isNull() && responseDoc.isObject()) {
            responseJson = responseDoc.object();
        }
    } else {
        qDebug() << "Error fetching content: " << reply->errorString();
    }
    reply->deleteLater();
    return responseJson;
}

void BlastOpePage::handleFeaturePermission(QWebEnginePage *page, const QUrl &securityOrigin,
                                           QWebEnginePage::Feature feature) {
    if (feature == QWebEnginePage::MediaAudioCapture ||
        feature == QWebEnginePage::MediaAudioVideoCapture ||
        feature == QWebEnginePage::MediaVideoCapture) {
        page->setFeaturePermission(securityOrigin, feature,
                                   QWebEnginePage::PermissionGrantedByUser);
    } else {
        page->setFeaturePermission(securityOrigin, feature, QWebEnginePage::PermissionDeniedByUser);
    }
}

QJsonObject BlastOpePage::getMetaInfo() {
    QJsonObject metaInfo;
    QString certName;
    QString certNo;

    QMap<QString, QString> userInfo = RegistryManager::instance()->getCurentLoginUser();
    certName = userInfo.value("certName", "");
    certNo = userInfo.value("identity", "");
    metaInfo["certName"] = certName;
    metaInfo["certNo"] = certNo;
    return metaInfo;
}

void BlastOpePage::initPagination() {
    pageWidget = new PageWidget;
    connect(pageWidget, &PageWidget::currentPageChanged, this, &BlastOpePage::PageChanged);
    connect(pageWidget->getComboBox(), QOverload<int>::of(&QComboBox::currentIndexChanged), this,
            &BlastOpePage::onComboBoxIndexChanged);
    ui->verticalLayout_4->addWidget(pageWidget);
    ;
    pageSize = 10;
    currentPage = 1;
    RefreshData();
}

void BlastOpePage::RefreshData() { loadDataFromSource(currentPage, pageSize); }

void BlastOpePage::loadDataFromSource(int currentPage, int pageSize) {
    PaginatedHProjectResult result = dao.getAllHProjectsByOpera(currentPage, pageSize);
    QList<QSharedPointer<HProject>> projectList = result.projects;
    totalCount = result.totalCount;
    pageWidget->setMaxPage(ceil(static_cast<double>(totalCount) / pageSize));

    model = new QStandardItemModel(this);

    headers = {
        {"选择", ""},  // 新增选择列
        {"工程名称", "name"},
        {"操作员", "operatorName"},
        {"爆破员", "blasterName"},
        {"井下地址", "addressPath"},
        {"雷管数量", "detSum"},
        {"起爆器数量", "blastCount"},
        {"起爆状态", "blastStatus"},
        {"进度", ""},
        {"操作", ""},
    };

    int headerCount = headers.size();
    QStringList headerLabels;
    QMap<int, QString> propMap;
    for (int i = 0; i < headers.size(); ++i) {
        headerLabels << headers[i].label;
        propMap[i] = headers[i].prop;
    }
    model->setHorizontalHeaderLabels(headerLabels);
    for (int row = 0; row < projectList.size(); ++row) {
        HProject &HProject = *projectList.at(row).data();
        QStandardItem *uuidItem = new QStandardItem();
        uuidItem->setData(HProject.getUuid(), Qt::UserRole);
        model->setItem(row, headerCount, uuidItem);
        for (int col = 0; col < headerCount; ++col) {
            QString prop = propMap[col];
            QStandardItem *item = nullptr;
            if (col == 0) {
                item = new QStandardItem();
                item->setCheckable(true);
                item->setCheckState(Qt::Unchecked);
                item->setText("");
            }
            if (!prop.isEmpty()) {
                QMetaProperty metaProp = HProject.metaObject()->property(
                    HProject.metaObject()->indexOfProperty(prop.toUtf8()));
                QVariant value = metaProp.read(&HProject);

                if (prop == "blastStatus") {
                    QString statusText;
                    if (value.toString() == BlastStatus::Created) {
                        statusText = "未 注 册";
                        item = new QStandardItem(statusText);
                        item->setForeground(QColor("#e7c66b"));
                    } else if (value.toString() == BlastStatus::Registered) {
                        statusText = "待安全确认";
                        item = new QStandardItem(statusText);
                        item->setForeground(QColor("#f3a361"));
                    } else if (value.toString() == BlastStatus::SafeChecked) {
                        statusText = "待起爆";
                        item = new QStandardItem(statusText);
                        item->setForeground(QColor("#f3a3k'k1"));
                    } else if (value.toString() == BlastStatus::Blasted) {
                        statusText = "起 爆 完 成";
                        item = new QStandardItem(statusText);
                        item->setForeground(QColor("#90d543"));
                    } else {
                        item = new QStandardItem(value.toString());
                    }
                } else {
                    item = new QStandardItem(value.toString());
                }
            }
            if (item) {
                item->setTextAlignment(Qt::AlignCenter);  // 设置文本居中对齐
                model->setItem(row, col, item);
            }
        }
    }
    ui->tableView->setModel(model);

    connectionItem = QObject::connect(model, &QStandardItemModel::itemChanged, this,
                                      &BlastOpePage::onItemCheckboxChanged);
    ui->tableView->setColumnWidth(0, 30);
    for (int i = 1; i < headerCount; ++i) {
        if (i == 8) {  // Column: 进度
            ui->tableView->horizontalHeader()->setSectionResizeMode(i, QHeaderView::Custom);
            ui->tableView->setColumnWidth(i, 180);
        } else {
            ui->tableView->horizontalHeader()->setSectionResizeMode(i, QHeaderView::Stretch);
        }
    }

    ui->tableView->setColumnHidden(headerCount, true);

    ui->tableView->setAlternatingRowColors(true);
    ui->tableView->verticalHeader()->setDefaultSectionSize(50);

    for (int row = 0; row < projectList.size(); ++row) {
        int progressCol = headers.size() - 2;  //
        QProgressBar *progressBar1 = new QProgressBar(ui->tableView);
        progressBar1->setRange(0, 100);  // 设置范围为0到100
        progressBar1->setValue(0);
        progressBar1->setAlignment(Qt::AlignCenter);
        progressBar1->setStyleSheet(
            "QProgressBar { border: 1px solid grey; border-radius: 5px; background-color: #EEEEEE; "
            "height: 10px; }"
            "QProgressBar::chunk { background-color: #05B8CC; width: 2px; margin: 0.5px; border - "
            "radius: 10px; }");
        progressBar1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

        QProgressBar *progressBar2 = new QProgressBar(ui->tableView);
        progressBar2->setRange(0, 100);  // 设置范围为0到100
        progressBar2->setValue(0);
        progressBar2->setAlignment(Qt::AlignCenter);
        progressBar2->setStyleSheet(
            "QProgressBar { border: 1px solid grey; border-radius: 5px; background-color: #EEEEEE; "
            "height: 10px; }"
            "QProgressBar::chunk { background-color: #05B8CC; width: 2px; margin: 0.5px; border - "
            "radius: 10px; }");
        progressBar2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

        QProgressBar *progressBar3 = new QProgressBar(ui->tableView);
        progressBar3->setRange(0, 100);  // 设置范围为0到100
        progressBar3->setValue(0);
        progressBar3->setAlignment(Qt::AlignCenter);
        progressBar3->setStyleSheet(
            "QProgressBar { border: 1px solid grey; border-radius: 5px; background-color: #EEEEEE; "
            "height: 10px; }"
            "QProgressBar::chunk { background-color: #05B8CC; width: 2px; margin: 0.5px; border - "
            "radius: 10px; }");
        progressBar3->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

        progressBars.append(ProgressBarTriple(progressBar1, progressBar2, progressBar3));
        QHBoxLayout *progressBarLayout = new QHBoxLayout;
        progressBarLayout->addWidget(progressBar1);
        progressBarLayout->addWidget(progressBar2);
        progressBarLayout->addWidget(progressBar3);
        progressBarLayout->setAlignment(Qt::AlignCenter);
        progressBarLayout->setContentsMargins(0, 0, 0, 0);
        progressBarLayout->setSpacing(0);  // 设置进度条之间的间距为0
        QWidget *progressBarContainer = new QWidget(ui->tableView);
        progressBarContainer->setLayout(progressBarLayout);
        QModelIndex progressIndex = model->index(row, progressCol);
        if (progressIndex.isValid()) {
            ui->tableView->setIndexWidget(progressIndex, progressBarContainer);
        }
        int col = headers.size() - 1;
        // 创建一个按钮
        QWidget *widget = new QWidget(ui->tableView);
        QPushButton *button = new QPushButton(widget);
        button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

        QModelIndex statusIndex = model->index(row, propMap.key("blastStatus"));
        if (statusIndex.isValid()) {
            QString blastStatus = model->data(statusIndex).toString();
            if (blastStatus == "起 爆 完 成") {
                // 为按钮添加图标，这里假设图标文件名为 icon.png，你需要根据实际情况修改
                QIcon icon(":/icons/icons/svg/blast.svg");
                button->setIcon(icon);
                button->setIconSize(QSize(32, 32));  // 设置图标大小
                button->setStyleSheet(
                    "QPushButton {"
                    "    padding: 0px;"
                    "    border: none;"
                    "    background-color: transparent;"
                    "}");
            } else if (blastStatus == "待起爆") {
                button->setText(startBlastButtonTxt);
                button->setEnabled(true);
            } else {
                button->setText("待安全员确认");
                button->setDisabled(true);
            }
        }
        QHBoxLayout *layout = new QHBoxLayout(widget);
        layout->addWidget(button);
        layout->setAlignment(Qt::AlignCenter);
        layout->setContentsMargins(0, 0, 0, 0);
        widget->setLayout(layout);

        QModelIndex index = model->index(row, col);
        if (index.isValid()) {
            ui->tableView->setIndexWidget(index, widget);
            connect(button, &QPushButton::clicked,
                    [this, row, button]() { handleButtonClick(row, button); });
        }
    }
}

// 切换页数
void BlastOpePage::PageChanged(int page) {
    currentPage = page;
    loadDataFromSource(currentPage, pageSize);
}

void BlastOpePage::onComboBoxIndexChanged(int index) {
    QVariant variant = pageWidget->getComboBox()->itemData(index);
    int value = variant.toInt();
    pageSize = value;
    currentPage = 1;
    loadDataFromSource(currentPage, pageSize);
}

void BlastOpePage::updateProgressBar(int value, int row) {
    if (!progressBars.isEmpty()) {
        QProgressBar *progressBar1 = progressBars[row].bar1;
        QProgressBar *progressBar2 = progressBars[row].bar2;
        QProgressBar *progressBar3 = progressBars[row].bar3;
        switch (value) {
            case 1:
                // 检查状态
                progressBar1->setRange(0, 0);  // 设置范围为0到100
                progressBar1->setValue(0);
                break;
            case 2:
                // 检查完成
                progressBar1->setRange(0, 100);  // 设置范围为0到100
                progressBar1->setValue(100);
                break;
            case 3:
                // 充电开始
                progressBar2->setRange(0, 0);  // 设置范围为0到100
                progressBar2->setValue(0);
                break;
            case 4:
                // 充电完成
                progressBar2->setRange(0, 100);  // 设置范围为0到100
                progressBar2->setValue(100);
                break;
            case 5:
                // 起爆中
                progressBar3->setRange(0, 0);  // 设置范围为0到100
                progressBar3->setValue(0);
                break;
            case 6:
                // 充电完成
                progressBar3->setRange(0, 100);  // 设置范围为0到100
                progressBar3->setValue(100);
                break;
            case 0:
                progressBar1->setRange(0, 100);
                progressBar1->setValue(0);
                progressBar2->setRange(0, 100);
                progressBar2->setValue(0);
                progressBar3->setRange(0, 100);
                progressBar3->setValue(0);
                break;
            default:
                break;
        }
    }
}

void BlastOpePage::onUpdateBlastStatus(int status, int row) {
    QModelIndex index = model->index(row, 7);
    if (index.isValid()) {
        QColor customColor;
        QFont boldFont;
        boldFont.setBold(true);
        switch (status) {
            case 0:
                model->setData(index, "待起爆");
                customColor = QColor("#44035b");
                model->setData(index, customColor, Qt::ForegroundRole);
                model->setData(index, boldFont, Qt::FontRole);
                break;
            case 1:
                model->setData(index, "组 网 中 ...");
                customColor = QColor("#44035b");
                model->setData(index, customColor, Qt::ForegroundRole);
                model->setData(index, boldFont, Qt::FontRole);
                break;
            case 2:
                model->setData(index, "组 网 完 成");
                customColor = QColor("#404185");
                model->setData(index, customColor, Qt::ForegroundRole);
                break;

            case 3:
                model->setData(index, "充 电 中 ...");
                customColor = QColor("#31688e");
                model->setData(index, customColor, Qt::ForegroundRole);
                break;
            case 4:
                model->setData(index, "充 电 完 成");
                customColor = QColor("#1f918d");
                model->setData(index, customColor, Qt::ForegroundRole);
                break;
            case 5:
                model->setData(index, "起 爆 中 ...");
                customColor = QColor("#38b775");
                model->setData(index, customColor, Qt::ForegroundRole);
                break;
            case 6:
                model->setData(index, "起 爆 完 成");
                customColor = QColor("#90d543");
                model->setData(index, customColor, Qt::ForegroundRole);
                break;
            // case 0:
            //     model->setData(index, "已 注 册");
            //     customColor = QColor("#8e620");
            //     model->setData(index, customColor, Qt::ForegroundRole);
            //     break;
            case 10:
                model->setData(index, "按 下 双 建 起 爆 ...");
                customColor = QColor("#8e620");
                model->setData(index, customColor, Qt::ForegroundRole);
                break;
            default:
                break;
        }
    }
}

void BlastOpePage::handleButtonClick(int row, QPushButton *button) {
    QStandardItem *uuidItem = model->item(row, 10);
    QString uuid;
    if (uuidItem) {
        QVariant uuidVariant = uuidItem->data(Qt::UserRole);
        if (uuidVariant.isValid()) {
            uuid = uuidVariant.toString();
        }
    }

    if (button->text() == startBlastButtonTxt) {
        button->setMinimumWidth(120);
        button->setText(stopBlastButtonTxt);
        firingWidget *widget = new firingWidget(row, false, uuid);
        connect(widget, &firingWidget::progressChanged, this, &BlastOpePage::updateProgressBar);
        connect(widget, &firingWidget::updateBlastStatus, this, &BlastOpePage::onUpdateBlastStatus);
        connect(widget, &firingWidget::updateButton, this, &BlastOpePage::changeButByMqtt);
        connect(widget, &firingWidget::countdown, this, &BlastOpePage::showDownWidget);
        connect(widget, &firingWidget::updateProjectStatus, this, &BlastOpePage::updateProject);
        connect(widget, &firingWidget::closeFiring, this, &BlastOpePage::destroyFiringWidget);
        if (isShowTriggeringWidget) {
            widget->show();
        }

        widget->setAttribute(Qt::WA_DeleteOnClose);
        uuidWidgetMap.insert(uuid, widget);

    } else if (button->text() == stopBlastButtonTxt) {
        firingWidget *widget = uuidWidgetMap.value(uuid);
        if (widget) {
            widget->cancelBlasting();
        }
    }
}

void BlastOpePage::changeButByMqtt(int status, int row) {
    qDebug() << "statusButton:" << status;
    QModelIndex index = model->index(row, 8);
    if (index.isValid()) {
        QWidget *widget = ui->tableView->indexWidget(index);
        if (widget) {
            QPushButton *button = widget->findChild<QPushButton *>();
            if (button) {
                // 使用样式表设置图标居中
                button->setStyleSheet(
                    "QPushButton {"
                    "    padding: 0px;"
                    "    border: none;"
                    "    background-color: transparent;"
                    "}");

                // 添加图标，假设图标文件名为 blast.svg，并且该文件存在于项目资源中
                QIcon icon(":/icons/icons/svg/blast.svg");
                button->setText("");
                button->setIcon(icon);
                button->setIconSize(QSize(32, 32));
            }
        }
    }
}

void BlastOpePage::updateProject(QString uuid) { dao.updateBlastStatusByUuid(uuid, "3"); }

void BlastOpePage::destroyFiringWidget(const QString &uuid) {
    firingWidget *widget = uuidWidgetMap.value(uuid);
    if (widget) {
        widget->close();             // 关闭窗口
        widget->deleteLater();       // 释放内存
        uuidWidgetMap.remove(uuid);  // 从映射中移除
    }
}

// 槽函数，当 item 状态改变时触发
void BlastOpePage::onItemCheckboxChanged(QStandardItem *item) {
    if (item->column() == 0) {  // 仅处理第一列的勾选状态改变
        if (item->checkState() == Qt::Checked) {
            QStandardItem *uuidItem = model->item(item->row(), 10);
            if (uuidItem) {
                QVariant uuidVariant = uuidItem->data(Qt::UserRole);
                if (uuidVariant.isValid()) {
                    QString uuid = uuidVariant.toString();
                    uuidMap[item->row()] = uuid;
                }
            }
        } else if (item->checkState() == Qt::Unchecked) {
            QStandardItem *uuidItem = model->item(item->row(), 10);
            if (uuidItem) {
                // 从 item 中获取 uuid 数据
                QVariant uuidVariant = uuidItem->data(Qt::UserRole);
                if (uuidVariant.isValid()) {
                    QString uuid = uuidVariant.toString();
                    // 从数组中移除该 uuid
                    uuidMap.remove(item->row());
                }
            }
        }
    }
}

void BlastOpePage::on_btnSelect_clicked() {
    // 禁用表格第一列的选项
    for (int row = 0; row < model->rowCount(); ++row) {
        QStandardItem *item = model->item(row, 0);
        if (item) {
            Qt::ItemFlags flags = item->flags();
            flags &= ~Qt::ItemIsEnabled;
            item->setFlags(flags);
        }
    }

    for (auto it = uuidMap.begin(); it != uuidMap.end(); ++it) {
        int row = it.key();
        QString uuid = it.value();
        firingWidget *widgetSelect = new firingWidget(row, true, uuid);
        QModelIndex index = model->index(row, 9);
        if (index.isValid()) {
            QWidget *widgetButton = ui->tableView->indexWidget(index);
            if (widgetButton) {
                QPushButton *button = widgetButton->findChild<QPushButton *>();
                button->setText("取消起爆流程");
            }
        }

        // 信号连接
        connect(widgetSelect, &firingWidget::progressChanged, this,
                &BlastOpePage::updateProgressBar);
        connect(widgetSelect, &firingWidget::updateBlastStatus, this,
                &BlastOpePage::onUpdateBlastStatus);
        connect(widgetSelect, &firingWidget::selectSignal, this, &BlastOpePage::handleSelect);
        connect(widgetSelect, &firingWidget::updateButton, this, &BlastOpePage::changeButByMqtt);
        connect(widgetSelect, &firingWidget::updateProjectStatus, this,
                &BlastOpePage::updateProject);
        connect(widgetSelect, &firingWidget::closeFiring, this,
                &BlastOpePage::destroyFiringWidgetSelect);
        widgetSelect->show();
        widgetSelect->setAttribute(Qt::WA_DeleteOnClose);
        uuidWidgetSMap.insert(uuid, widgetSelect);
    }
}

// 完成充电
void BlastOpePage::handleSelect(QString uuid) {
    selectedUuids.insert(uuid);
    bool isSame = checkUuidsSame();
    if (isSame) {
        bool successSelect;
        serialTool = SerialTool::getInstance(nullptr, &successSelect);
        connect(serialTool, &SerialTool::buttonPressedReceived, this,
                &BlastOpePage::showDownWidgetSelect, Qt::SingleShotConnection);
        if (serialTool) {
            QByteArray data = "\r\nENABLE_BUTTON\r\n";
            bool success = serialTool->sendData(data);
            if (success) {
                Logger::getInstance().info("blast triggered.");
            } else {
                Logger::getInstance().warn("blast trigger failed.");
            }
            connect(
                serialTool, &SerialTool::enableButtonReceived, this,
                [this]() {
                    for (const auto &row : uuidMap.keys()) {
                        qDebug() << "Key:" << row;
                        onUpdateBlastStatus(10, row);
                    }
                },
                Qt::SingleShotConnection);

            // TODO: receive blast record
        } else {
            qDebug() << "serialTool Not fond.";
            QMessageBox::critical(nullptr, "错误", "trigger button devices not found");
        }
    } else {
        Logger::getInstance().error(
            QString("The uuids in selectedUuids and uuidMap are different. uuid: %1").arg(uuid));
    }
}

// 检查 selectedUuids 和 uuidMap 中的 uuid 是否相同
bool BlastOpePage::checkUuidsSame() {
    QSet<QString> mapUuids;
    for (const auto &value : uuidMap) {
        qDebug() << "value" << value;
        mapUuids.insert(value);
    }
    return selectedUuids == mapUuids;
}

void BlastOpePage::showDownWidgetSelect() {
    QByteArray data = "\r\nDISABLE_BUTTON\r\n";
    bool success = serialTool->sendData(data);
    if (success) {
        qDebug() << "Data sent successfully";
    } else {
        qDebug() << "Failed to send data";
    }
    serialTool->releaseInstance();
    CountdownWidget *countdownWidgetSelect = new CountdownWidget(this);
    countdownWidgetSelect->resize(200, 200);
    int x = (this->width() - countdownWidgetSelect->width()) / 2;
    int y = (this->height() - countdownWidgetSelect->height()) / 2;

    countdownWidgetSelect->move(x, y);
    countdownWidgetSelect->show();

    connect(countdownWidgetSelect, &CountdownWidget::countdownFinished, this,
            &BlastOpePage::triggerBlastSelected, Qt::SingleShotConnection);
}

void BlastOpePage::triggerBlastSelected() {
    for (auto it = uuidWidgetSMap.begin(); it != uuidWidgetSMap.end(); ++it) {
        QString uuid = it.key();
        firingWidget *widget = it.value();
        QString topic = "hxgc/" + uuid + "/P";
        QString message = "起爆";
        widget->onCountdownFinished(topic, message);
    }
}

void BlastOpePage::destroyFiringWidgetSelect(const QString &uuid) {
    firingWidget *widget = uuidWidgetSMap.value(uuid);
    if (widget) {
        widget->close();
        widget->deleteLater();
        uuidWidgetSMap.remove(uuid);
    }
    for (int row = 0; row < model->rowCount(); ++row) {
        QStandardItem *item = model->item(row, 0);
        if (item) {
            Qt::ItemFlags flags = item->flags();
            flags &= ~Qt::ItemIsEnabled;  // 去除 ItemIsEnabled 标志位
            item->setFlags(flags);
        }
    }
}
