#include "mainwindow.h"


MainWindow* MainWindow::sp_this=nullptr;

MainWindow::MainWindow()
{
    sp_this=this;
    
    LogHandler::Get().installMessageHandler();
    QString inifile=QCoreApplication::applicationDirPath()+"/gameras.ini";
    
    qSetting = new QSettings(inifile,QSettings::IniFormat);
    qSetting->setIniCodec(QTextCodec::codecForName("UTF-8"));
    
    modelPaths=qSetting->value("licensePlateRecognition/model_paths").toString();
    
    initCommon();
    
    deleteLogFileTimer =new QTimer(this);
    connect(deleteLogFileTimer, &QTimer::timeout, this, &MainWindow::deleteLogFile);
    int deleteLogfileTimer=qSetting->value("timer/delete_logfile_timer").toInt();
    deleteLogFileTimer->start(deleteLogfileTimer);
    
    deleteFrameFileTimer =new QTimer(this);
    int deMkvflieTimer=qSetting->value("timer/delete_mkvflie_timer").toInt();
    connect(deleteFrameFileTimer,&QTimer::timeout,this,&MainWindow::deleteMkvFileTimer);
    deleteFrameFileTimer->start(deMkvflieTimer);
    
    initFaceFaceRecognition();

    FaceReconition &faceRecognition = FaceReconition::getInstance();
    float confidence=qSetting->value("devices/confidence").toFloat();
    if(localImageMap.size()>0){
        faceRecognition.initSourceImageMap(localImageMap,confidence);
    }

    float carConfidence=qSetting->value("devices/carConfidence").toFloat();
    //LicensePlateRecognition &licensePlateRecogn =LicensePlateRecognition::getInstance();
    //licensePlateRecogn.initHlprContext(modelPaths,qSetting->value("licensePlateRecognition/car_cascade_path").toString(),carConfidence);
    QString httpurl;
    QString profile=qSetting->value("cloudservice/profile","test").toString();
    if(strcmp(profile.toUtf8().data(),vides_data::PROFLIE_TEST)==0){
        httpurl=qSetting->value("cloudservice/test_http").toString();
    }else{
        httpurl=qSetting->value("cloudservice/pro_http").toString();
    }
    MediaFaceImage* mediaFaceImage= MediaFaceImage::getInstance();
    QString configPath = qSetting->value("devices/sz_config_path").toString();
    QString tempPath = qSetting->value("devices/sz_temp_path").toString();
    int sdk_handle= mediaFaceImage->SdkInit(configPath,tempPath);
    qDebug()<<"句柄为:"<<sdk_handle;
    if(sdk_handle<0){
        qInfo() << "sdk初始化失败";
        return;
    }
    connect(this, SIGNAL(shutdownSignals(QString,int)), this, SLOT(clearHandle(QString,int)),Qt::QueuedConnection);
    
    
    dePermissionSynTimer=new QTimer(this);
    int dePermissionTimer=qSetting->value("timer/device_permission_syn_timer").toInt();
    connect(dePermissionSynTimer, &QTimer::timeout, this, [this, httpurl](){
        this->startCamera(httpurl);
    },Qt::QueuedConnection);
    dePermissionSynTimer->start(dePermissionTimer);
    
    connect(&server, &QTcpServer::newConnection, this, &MainWindow::handleMatNewConnection);

    int port=qSetting->value("localservice/port").toInt();
    
    if (!server.listen(QHostAddress::Any, port)) {
        qInfo() << "Error: Unable to start the server on port 12345";
    } else {
        qDebug() << "Server started, listening on port 12345";
    }
}

void MainWindow::sendJsonResponse(QTcpSocket* socket, int code, const QString& data, const QString& msg){
    QJsonObject jsonResponse;
    jsonResponse["code"] = code;
    jsonResponse["data"] = data;
    jsonResponse["msg"] = msg;
    
    QJsonDocument doc(jsonResponse);
    QByteArray jsonData = doc.toJson();
    
    socket->write(jsonData);
    socket->flush();
    socket->waitForBytesWritten();
    socket->disconnectFromHost();
}

void MainWindow::sendEmptyResponse(QTcpSocket* socket){
    sendJsonResponse(socket, 200, "", "Success");
}

void MainWindow::sendNotFoundResponse(QTcpSocket* socket){
    QString httpResponse = "HTTP/1.1 404 Not Found\r\n"
                           "Content-Type: text/html\r\n"
                           "Connection: Close\r\n\r\n"
                           "<html><body><h1>404 Not Found</h1>"
                           "<p>The requested URL was not found on this server.</p></body></html>";
    
    socket->write(httpResponse.toUtf8());
    socket->flush();
    socket->waitForBytesWritten();
    socket->disconnectFromHost();
}
void MainWindow::handleMatNewConnection(){
    QTcpSocket* socket = server.nextPendingConnection();
    
    QObject::connect(socket, &QTcpSocket::readyRead, [&, socket](){
        QByteArray requestData = socket->readAll();
        QString request(requestData);
        
        QRegExp urlRegEx("GET /cameras/([^/]+)/current_image HTTP");
        if(urlRegEx.indexIn(request) != -1) {
            QString sn = urlRegEx.cap(1);
            qDebug() << "Requested Camera SN: " << sn;
            bool foundCamera = false;
            for (auto it = faceDetectionParkingPushs.begin(); it != faceDetectionParkingPushs.end(); ++it) {
                QString currentSn = it->second->getSSn();
                if (currentSn == sn) {
                    CameraHandle* matchedHandle = it->second;
                    std::vector<uchar> buffer;
                    matchedHandle->getCurrentFrame(buffer);
                    
                    QByteArray byteArray(reinterpret_cast<const char*>(buffer.data()), buffer.size());
                    QString base64Data = byteArray.toBase64();
                    
                    sendJsonResponse(socket, 200, base64Data, "Success");
                    foundCamera = true;
                    break;
                }
            }
            
            if(!foundCamera){
                sendEmptyResponse(socket);
            }
        } else {
            sendNotFoundResponse(socket);
        }
    });
}

void MainWindow::modifyImagesAndNames(QString &modId){
    QString fullPathName;
    Common & instace= Common::getInstance();
    if(cloudImageMap.count(modId) <=0 ){
        return;
    }
    QString ossUrl= cloudImageMap.at(modId);
    HttpService httpService(ossUrl);
    
    vides_data::response *res= httpService.httpDownload(instace.getImages(),fullPathName);
    if(res->code!=0){
        qInfo()<<"httpFindCameras请求失败";
        instace.deleteObj(res);
        return ;
    }
    QString settingKey = QString("%1").arg(modId);
    qSetting->setValue(settingKey,fullPathName);
    localImageMap[modId]=fullPathName;
    instace.deleteObj(res);
}

void MainWindow::removeImageFiles(QString id){
    auto localIt = localImageMap.find(id);
    if (localIt != localImageMap.end()) {
        QString value = localIt->second;
        QFile file(value);
        if (!file.open(QIODevice::WriteOnly)) {
            qDebug() << "removeImageFiles open fail" << value;
        } else {
            file.remove();
        }
    }
}
void MainWindow::updateLocalFace(const QString &httpurl) {
    Common &instance = Common::getInstance();
    HttpService httpService(httpurl);
    QString serialNumber;
    std::list<vides_data::responseFaceReconition*> datas;
    this->findLocalSerialNumber(serialNumber);
    vides_data::response *res = httpService.httpFindFaceReconition(serialNumber, datas);
    
    if (res->code != 0) {
        qInfo() << "httpFindCameras请求失败";
        instance.deleteObj (res); // 手动释放资源
        return;
    }
    
    QSet<QString> dataIds;
    bool isChanged=false;
    for (const auto& item : datas) {
        dataIds.insert(item->img);
        
        if (cloudImageMap.count(item->id) > 0) {
            if (cloudImageMap.at(item->id) != item->img) {
                qSetting->beginGroup("cloudImageMap");
                QString settingKey = QString("%1").arg(item->id);
                qSetting->setValue(settingKey, item->img);
                qSetting->endGroup();
                
                cloudImageMap[item->id] = item->img;
                removeImageFiles(item->id);
                qSetting->beginGroup("localImageMap");
                this->modifyImagesAndNames(item->id);
                qSetting->endGroup();
                isChanged=true;
            }
        } else {
            qSetting->beginGroup("cloudImageMap");
            QString settingKey = QString("%1").arg(item->id);
            qSetting->setValue(settingKey, item->img);
            qSetting->endGroup();
            
            cloudImageMap[item->id] = item->img;
            
            qSetting->beginGroup("localImageMap");
            this->modifyImagesAndNames(item->id);
            qSetting->endGroup();
            isChanged=true;
        }
    }
    
    for (auto it = cloudImageMap.begin(); it != cloudImageMap.end();) {
        if (!dataIds.contains(it->second)) {
            qSetting->beginGroup("cloudImageMap");
            qSetting->remove(it->first);
            qSetting->endGroup();
            auto localIt = localImageMap.find(it->first);
            if (localIt != localImageMap.end()) {
                QFile file(localIt->second);
                if (!file.open(QIODevice::WriteOnly)) {
                    qDebug() << "open fail" << localIt->second;
                } else {
                    file.remove();
                    qSetting->beginGroup("localImageMap");
                    qSetting->remove(localIt->first);
                    qSetting->endGroup();
                    
                    localImageMap.erase(localIt);
                }
            }
            isChanged=true;
            it = cloudImageMap.erase(it);
        } else {
            ++it;
        }
    }
    
    FaceReconition &faceRecognition = FaceReconition::getInstance();
    if (isChanged) {
        if (cloudImageMap.empty()) {
            // 如果云端映射现在为空，移除所有特征
            faceRecognition.featureRemove();
        } else {
            float confidence=qSetting->value("devices/confidence").toFloat();
            qDebug()<<"startMap != endMap-->";
            faceRecognition.initSourceImageMap(localImageMap,confidence);
        }
    }
    instance.deleteObj(res);
}

void MainWindow::findLocalSerialNumber(QString &serialNumber){
    if(vides_data::isVirtualMachine()){
        serialNumber = QSysInfo::machineUniqueId();
    }else{
        serialNumber =vides_data::getSerialNumber();
        if (!serialNumber.isEmpty()) {
            qDebug() << "CPU Serial Number:" << serialNumber;
        } else {
            qDebug() << "CPU Serial Number not found!";
            return;
        }
    }
}
void MainWindow::clearHandle(QString sDevId, int nDevPort){
    QString key = sDevId + ":" + QString::number(nDevPort);
    Common & instace= Common::getInstance();
    auto it = this->faceDetectionParkingPushs.find(key);
    if (it != this->faceDetectionParkingPushs.end()) {
        MediaFaceImage* mediaFaceImage= MediaFaceImage::getInstance();
        
        qDebug()<<"clearHandle:离线的设备是:"<<key;
        CameraHandle* offlineCameraHandle = it->second; // 注意使用->second获取值
        int hDevice=offlineCameraHandle->getHdevice();
        instace.deleteObj(offlineCameraHandle);
        this->faceDetectionParkingPushs.erase(it); // 使用迭代器来删除，更安全，避免潜在的问题
        mediaFaceImage->clearCurrentDevice(hDevice);
    }
}
void MainWindow::clearOfflineCameraHandle(QString sDevId, int nDevPort) {
    emit shutdownSignals(sDevId,nDevPort);
}
//平台有 盒子没有 盒子开启
//平台没有 盒子有 盒子关闭
void MainWindow::startCamera(const QString &httpurl){
    Common & instace= Common::getInstance();
    MediaFaceImage* mediaFaceImage= MediaFaceImage::getInstance();
    QString nonConstHttpUrl = std::remove_const<QString>::type(httpurl);

    vides_data::responseDeviceData devices;
    // QString serialNumber = QSysInfo::machineUniqueId();
    QString serialNumber;
    findLocalSerialNumber(serialNumber);

    vides_data::requestDeviceStatus reStatus;
    reStatus.sSn=serialNumber;
    reStatus.status=1;
    reStatus.type=1;
    reStatus.ip_addr=instace.GetLocalIp();

    HttpService httpService(httpurl);
    vides_data::response *res=httpService.httpPostDeviceStatus(reStatus);
    if(res->code!=0){
        qInfo()<<"盒子状态上报失败 code:"<<res->code<<"msg:"<<res->data;
    }
    instace.deleteObj(res);

    httpService.setHttpUrl(httpurl);
    vides_data::response *re= httpService.httpFindCameras(serialNumber,devices);
    if(re->code==0 || re->code==20004){
        QString username = qSetting->value("devices/username").toString();
        QString password = qSetting->value("devices/password").toString();
        std::map<QString,vides_data::localDeviceStatus*> localDevices;
        mediaFaceImage->SdkSearchDevicesSyn(localDevices);
        if(localDevices.size()<=0){
            instace.deleteObj(re);
            return ;
        }
        for (const auto& device : devices.list) {
            if(localDevices.count(device.sSn)>0 ){
                vides_data::localDeviceStatus* localDevice= localDevices.at(device.sSn);
                QString ipAddress= QString("%1.%2.%3.%4").arg(localDevice->HostIP.c[0]).arg(localDevice->HostIP.c[1]).arg(localDevice->HostIP.c[2]).arg(localDevice->HostIP.c[3]);
                //this->gatewayRandomIp(ipAddress);
                QString key = ipAddress + ":" + QString::number(localDevice->TCPPort);
                if(faceDetectionParkingPushs.count(key)<=0){
                    httpService.setHttpUrl(httpurl);

                    vides_data::cameraParameters parameter;
                    parameter.sDevId=ipAddress;
                    parameter.nDevPort=localDevice->TCPPort;
                    parameter.sUserName=username;
                    parameter.sPassword=password;
                    parameter.channel=localDevice->ChannelNum;
                    parameter.httpUrl=nonConstHttpUrl;
                    parameter.sSn=device.sSn;
                    //parameter.rtspUrl="rtsp://192.168.10.131:554/user=admin&password=&channel=1&stream=1.sdp?";
                    //parameter.rtspUrl=std::move(QString("rtsp://admin:@%1/stream1").arg(ipAddress));
                    this->initCameras(parameter,device.areas);
                }
                else {
                    auto it = this->faceDetectionParkingPushs.find(key);
                    if (it != this->faceDetectionParkingPushs.end()) {
                        CameraHandle* offlineCameraHandle = it->second; // 注意使用->second获取值
                        if(!offlineCameraHandle->compareLists(device.areas)){
                            offlineCameraHandle->updateParkMapAndParkingSpaceInfos(device.areas);
                        }
                    }
                }
            }
        }
        this->deleteCloudNotCamer(localDevices, devices.list);

        for (auto& pair : localDevices) {
            if (pair.second != nullptr) {  // 如果对象未被删除（即不为nullptr）
                instace.deleteObj(pair.second);
            }
        }
        // 清空 localDevices 容器
        localDevices.clear();
    }

    updateLocalFace(httpurl);
    instace.deleteObj(re);

}

bool MainWindow::isDeviceInList(const QString& deviceId, const std::list<vides_data::responseDeviceStatus>& devices) {
    auto it = std::find_if(devices.begin(), devices.end(), [&deviceId](const vides_data::responseDeviceStatus& device) {
        return deviceId == device.sSn; // 假设 sSn 是 std::string 类型，需要转换
    });
    return it != devices.end(); // 如果迭代器不是end，说明找到了匹配项
}
//从localDevices中过滤出不在devices列表中的设备
void MainWindow::deleteCloudNotCamer(const std::map<QString, vides_data::localDeviceStatus*>& localDevices,
                                     const std::list<vides_data::responseDeviceStatus>& devices) {
    for (auto localDevice : localDevices) {
        vides_data::localDeviceStatus* value = localDevice.second; // 使用 .second 访问值
        if (!this->isDeviceInList(value->sSn, devices)) {
            QString ipAddress = QString("%1.%2.%3.%4").arg(value->HostIP.c[0]).arg(value->HostIP.c[1]).arg(value->HostIP.c[2]).arg(value->HostIP.c[3]);
            QString key = ipAddress + ":" + QString::number(value->TCPPort);
            clearOfflineCameraHandle(ipAddress,value->TCPPort);
        }
    }
}

void MainWindow::initDevConfigSyn(CameraHandle *cameraHandle){
    Common & instace= Common::getInstance();
    QString time= instace.getTimeString();
    cameraHandle->sdkDevSystemTimeZoneSyn(time);
    QString recor;
    iniRecordingToString(recor);
    QByteArray bRecor =recor.toUtf8();
    const char* cRecor=bRecor.data();
    cameraHandle->sdkRecordCfg(cRecor);
    QString enCode;
    iniEncodeToString(enCode);
    QByteArray bCode =enCode.toUtf8();
    const char* cCode=bCode.data();
    cameraHandle->sdkEncodeCfg(cCode);
}

void MainWindow::iniEncodeToString(QString &enCodeJson) {
    // 创建 JSON 对象
    QJsonObject rootObject;
    
    // 添加 ExtraFormat 到 JSON 对象中
    QJsonObject extraFormatObject;
    QJsonObject videoObjectExtra = {
        //        {"BitRate", qSetting->value("ExtraFormat/Video.BitRate").toInt()},
        {"BitRateControl", qSetting->value("ExtraFormat/Video.BitRateControl").toString()},
        {"Compression", qSetting->value("ExtraFormat/Video.Compression").toString()},
        {"FPS", qSetting->value("ExtraFormat/Video.FPS").toInt()},
        {"GOP", qSetting->value("ExtraFormat/Video.GOP").toInt()},
        {"Quality", qSetting->value("ExtraFormat/Video.Quality").toInt()},
        {"Resolution", qSetting->value("ExtraFormat/Video.Resolution").toString()},
        {"VirtualGOP", qSetting->value("ExtraFormat/Video.VirtualGOP").toInt()}
    };
    extraFormatObject["VideoEnable"] = qSetting->value("ExtraFormat/VideoEnable").toBool();
    extraFormatObject["AudioEnable"] = qSetting->value("ExtraFormat/AudioEnable").toBool();
    extraFormatObject["Video"] = videoObjectExtra;
    rootObject["ExtraFormat"] = extraFormatObject;
    
    // 添加 MainFormat 到 JSON 对象中
    QJsonObject mainFormatObject;
    QJsonObject videoObjectMain = {
        //        {"BitRate", qSetting->value("MainFormat/Video.BitRate").toInt()},
        {"BitRateControl", qSetting->value("MainFormat/Video.BitRateControl").toString()},
        {"Compression", qSetting->value("MainFormat/Video.Compression").toString()},
        {"FPS", qSetting->value("MainFormat/Video.FPS").toInt()},
        {"GOP", qSetting->value("MainFormat/Video.GOP").toInt()},
        {"Quality", qSetting->value("MainFormat/Video.Quality").toInt()},
        {"Resolution", qSetting->value("MainFormat/Video.Resolution").toString()},
        {"VirtualGOP", qSetting->value("MainFormat/Video.VirtualGOP").toInt()}
    };
    mainFormatObject["VideoEnable"] = qSetting->value("MainFormat/VideoEnable").toBool();
    mainFormatObject["AudioEnable"] = qSetting->value("MainFormat/AudioEnable").toBool();
    mainFormatObject["Video"] = videoObjectMain;
    rootObject["MainFormat"] = mainFormatObject;
    QJsonArray jsonArray;
    jsonArray.append(rootObject);
    
    // 将 JSON 对象转换为 JSON 文档
    QJsonDocument jsonDocument(jsonArray);
    enCodeJson = QString::fromUtf8(jsonDocument.toJson());
}

bool MainWindow::iniWorkSpVMn(vides_data::responseGb28181 *gb28181,QString &workSpWMn,QString &sn){
    qDebug()<<"iniWorkSpVMn=="<<sn;
    QString jsonfile=QCoreApplication::applicationDirPath()+"/camera_config.json";
    bool isEqual=true;
    
    // 读取 JSON 配置文件
    QFile file(jsonfile);
    if (!file.open(QIODevice::ReadOnly)) {
        qDebug() << "Failed to open the camera_config.json";
        return isEqual;
    }
    QJsonObject toJsonObject;
    
    // 解析 JSON 数据
    QByteArray jsonData = file.readAll();
    file.close();
    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData);
    QJsonObject rootObj = jsonDoc.object();
    
    // 获取 cameraconfigs 对象
    QJsonArray cameraConfigs = rootObj.value("cameraconfigs").toArray();
    bool found = false;
    for (int i = 0; i < cameraConfigs.size(); ++i) {
        QJsonObject config = cameraConfigs.at(i).toObject();
        if (config.contains("sn") && config.value("sn").toString() == sn) {
            found = true;
            QString Camreaid = config.value("Camreaid").toString();
            int iHsIntervalTime = config.value("iHsIntervalTime").toInt();
            int iRsAgedTime = config.value("iRsAgedTime").toInt();
            int sCsPort = config.value("sCsPort").toInt();
            QString szConnPass = config.value("szConnPass").toString();
            QString szCsIP = config.value("szCsIP").toString();
            QString szDeviceNO = config.value("szDeviceNO").toString();
            QString szServerDn = config.value("szServerDn").toString();
            QString szServerNo = config.value("szServerNo").toString();
            isEqual = (szCsIP == gb28181->sip_ip &&
                       sCsPort == gb28181->sip_port &&
                       szServerNo == gb28181->serial &&
                       szServerDn ==gb28181->realm &&
                       iRsAgedTime == gb28181->register_validity &&
                       iHsIntervalTime == gb28181->heartbeat_interval &&
                       szConnPass == gb28181->password &&
                       szDeviceNO == gb28181->device_id &&
                       Camreaid == gb28181->channel_id);
            if(!isEqual){
                config["Camreaid"]=gb28181->channel_id;
                config["szCsIP"]=gb28181->sip_ip ;
                config["szServerNo"]=gb28181->serial;
                config["sCsPort"]=gb28181->sip_port;
                config["szServerDn"]=gb28181->realm;
                config["iRsAgedTime"]=gb28181->register_validity;
                config["iHsIntervalTime"]=gb28181->heartbeat_interval;
                config["szConnPass"]=gb28181->password;
                config["szDeviceNO"]=gb28181->device_id;
                config["sn"]=sn;
                toJsonObject["szCsIP"]=gb28181->sip_ip ;
                toJsonObject["szServerNo"]=gb28181->serial;
                toJsonObject["sCsPort"]=gb28181->sip_port;
                toJsonObject["szServerDn"]=gb28181->realm;
                toJsonObject["iRsAgedTime"]=gb28181->register_validity;
                toJsonObject["iHsIntervalTime"]=gb28181->heartbeat_interval;
                toJsonObject["szConnPass"]=gb28181->password;
                toJsonObject["szDeviceNO"]=gb28181->device_id;
                
                QVariantList variantList;
                for (int i = 0; i < 64; ++i) {
                    variantList.append(QVariant(0));
                }
                
                QJsonArray levelArray = QJsonArray::fromVariantList(variantList);
                toJsonObject["AlarmLevel"]=levelArray;
                QStringList alarmidStrings;
                for (int i = 1; i <= 64; ++i) {
                    alarmidStrings.append("3402000000134000000" + QString::number(i, 10).rightJustified(2, '0'));
                }
                QJsonArray alarmidArray = QJsonArray::fromStringList(alarmidStrings);
                toJsonObject["Alarmid"]=alarmidArray;
                QVariantList variantListLevel;
                for (int i = 0; i < 64; ++i) {
                    variantListLevel.append(QVariant(0));
                }
                
                QJsonArray camreaLevelArray = QJsonArray::fromVariantList(variantListLevel);
                
                toJsonObject["CamreaLevel"]=camreaLevelArray;
                QStringList camreaidStrings;
                for (int i = 1; i <= 64; ++i) {
                    if(i==1){
                        camreaidStrings.append(gb28181->channel_id);
                    }else{
                        camreaidStrings.append("3402000000131000001" + QString::number(i, 10).rightJustified(2, '0'));
                    }
                }
                QJsonArray camreaidArray = QJsonArray::fromStringList(camreaidStrings);
                toJsonObject["Camreaid"]=camreaidArray;
                toJsonObject["HeartBeatCount"] = 0;
                toJsonObject["bCsEnable"] = true;
                toJsonObject["uiAlarmStateBlindEnable"] = static_cast<qint64>(4294967295);
                toJsonObject["uiAlarmStateConnectEnable"] = static_cast<qint64>(4294967295);
                toJsonObject["uiAlarmStateGpinEnable"] = static_cast<qint64>(4294967295);
                toJsonObject["uiAlarmStateLoseEnable"] = static_cast<qint64>(4294967295);
                toJsonObject["uiAlarmStateMotionEnable"] = static_cast<qint64>(4294967295);
                toJsonObject["uiAlarmStatePerformanceEnable"] = static_cast<qint64>(4294967295);
                toJsonObject["sUdpPort"] = 5060;
                cameraConfigs[i] = config; // 更新数组中的配置
                break;
            }
        }
    }
    if (!found) {
        QJsonObject newValue;
        newValue["sn"]=sn;
        newValue["Camreaid"]=gb28181->channel_id;
        newValue["szCsIP"]=gb28181->sip_ip ;
        newValue["szServerNo"]=gb28181->serial;
        newValue["sCsPort"]=gb28181->sip_port;
        newValue["szServerDn"]=gb28181->realm;
        newValue["iRsAgedTime"]=gb28181->register_validity;
        newValue["iHsIntervalTime"]=gb28181->heartbeat_interval;
        newValue["szConnPass"]=gb28181->password;
        newValue["szDeviceNO"]=gb28181->device_id;
        
        toJsonObject["szCsIP"]=gb28181->sip_ip ;
        toJsonObject["szServerNo"]=gb28181->serial;
        toJsonObject["sCsPort"]=gb28181->sip_port;
        toJsonObject["szServerDn"]=gb28181->realm;
        toJsonObject["iRsAgedTime"]=gb28181->register_validity;
        toJsonObject["iHsIntervalTime"]=gb28181->heartbeat_interval;
        toJsonObject["szConnPass"]=gb28181->password;
        toJsonObject["szDeviceNO"]=gb28181->device_id;
        
        QVariantList variantList;
        for (int i = 0; i < 64; ++i) {
            variantList.append(0);
        }
        
        QJsonArray levelArray = QJsonArray::fromVariantList(variantList);
        
        toJsonObject["AlarmLevel"]=levelArray;
        QStringList alarmidStrings;
        for (int i = 1; i <= 64; ++i) {
            alarmidStrings.append("3402000000134000000" + QString::number(i, 10).rightJustified(2, '0'));
        }
        QJsonArray alarmidArray = QJsonArray::fromStringList(alarmidStrings);
        toJsonObject["Alarmid"]=alarmidArray;
        QJsonArray camreaLevelArray;
        for (int i = 0; i < 64; ++i) {
            camreaLevelArray.append(0);
        }
        toJsonObject["CamreaLevel"]=camreaLevelArray;
        QStringList camreaidStrings;
        for (int i = 1; i <= 64; ++i) {
            if(i==1){
                camreaidStrings.append(gb28181->channel_id);
            }else{
                camreaidStrings.append("3402000000131000001" + QString::number(i, 10).rightJustified(2, '0'));
            }
        }
        QJsonArray camreaidArray = QJsonArray::fromStringList(camreaidStrings);
        toJsonObject["Camreaid"]=camreaidArray;
        toJsonObject["HeartBeatCount"] = 0;
        toJsonObject["bCsEnable"] = true;
        toJsonObject["uiAlarmStateBlindEnable"] = static_cast<qint64>(4294967295);
        toJsonObject["uiAlarmStateConnectEnable"] = static_cast<qint64>(4294967295);
        toJsonObject["uiAlarmStateGpinEnable"] = static_cast<qint64>(4294967295);
        toJsonObject["uiAlarmStateLoseEnable"] = static_cast<qint64>(4294967295);
        toJsonObject["uiAlarmStateMotionEnable"] = static_cast<qint64>(4294967295);
        toJsonObject["uiAlarmStatePerformanceEnable"] = static_cast<qint64>(4294967295);
        toJsonObject["sUdpPort"] = 5060;
        isEqual=false;
        cameraConfigs.append(newValue); // 添加新的配置到数组中
    }
    if(!isEqual){
        QJsonDocument doc(toJsonObject);
        QByteArray jsonData = doc.toJson(QJsonDocument::Compact);
        workSpWMn = QString::fromUtf8(jsonData);
        // 更新 JSON 数据
        rootObj["cameraconfigs"] = cameraConfigs;
        file.setFileName(jsonfile);
        if (!file.open(QIODevice::WriteOnly)) {
            qWarning("Cannot open file for writing");
            return true;
        }
        QJsonDocument saveDoc(rootObj);
        file.write(saveDoc.toJson());
        file.close();
        
    }
    return isEqual;
}

void MainWindow::iniRecordingToString(QString &recorJson){
    QJsonObject jsonObject;
    
    // 读取 Mask 数据
    QJsonArray maskArray;
    // 遍历所有掩码
    for (int i = 1; i <= 7; i++) {
        QString maskKey = QString("Mask/Mask_%1").arg(i);
        // 读取掩码值。存储为QStringList，就像在ini文件中定义的一样
        QStringList maskValues = qSetting->value(maskKey).toStringList();
        QJsonArray maskSubArray;
        
        foreach (const QString &value, maskValues) {
            maskSubArray.append(value.trimmed());
        }
        maskArray.append(maskSubArray);
    }
    
    jsonObject["Mask"] = maskArray;
    
    // 读取 Packet 数据
    jsonObject["PacketLength"] =qSetting->value("Packet/PacketLength").toInt();
    jsonObject["PreRecord"] = qSetting->value("Packet/PreRecord").toInt();
    jsonObject["RecordMode"] = qSetting->value("Packet/RecordMode").toString();
    jsonObject["Redundancy"] = qSetting->value("Packet/Redundancy").toBool();
    
    
    // 读取 TimeSection 数据
    QJsonArray timeArray;
    for (int ts = 1; ts <= 7; ts++) {
        QString tsKey = QString("TimeSection/TimeSection_%1").arg(ts);
        
        // 读取掩码值。存储为QStringList，就像在ini文件中定义的一样
        QStringList tsValues = qSetting->value(tsKey).toStringList();
        QJsonArray timeSubArray;
        foreach (const QString &value, tsValues) {
            timeSubArray.append(value.trimmed());
        }
        timeArray.append(timeSubArray);
    }
    jsonObject["TimeSection"] = timeArray;
    QJsonArray jsonArray;
    jsonArray.append(jsonObject);
    QJsonDocument jsonDocument(jsonArray);
    recorJson =  QString::fromUtf8(jsonDocument.toJson());
}
void MainWindow::initCameras(vides_data::cameraParameters &parameter,const std::list<vides_data::responseArea>&areas){
    MediaFaceImage* mediaFaceImage= MediaFaceImage::getInstance();
    float carConfidence=qSetting->value("devices/carConfidence").toFloat();
    int image_save=qSetting->value("devices/image_save").toInt();

    CameraHandle * cameraHandle =new CameraHandle(parameter.sDevId,parameter.httpUrl,parameter.sSn,parameter.channel,modelPaths,carConfidence,image_save);
    
    int sdk_handle=cameraHandle->sdkDevLoginSyn(parameter.sDevId,parameter.nDevPort,parameter.sUserName,parameter.sPassword,10000);
    qDebug()<<"句柄为2:"<<sdk_handle;
    if(sdk_handle<=0){
        qInfo() << "登录失败";
        return ;
    }
    initDevConfigSyn(cameraHandle);
    mediaFaceImage->setMap(sdk_handle,cameraHandle);
    
    cameraHandle->sdkDevSetAlarmListener(sdk_handle,1);
    int synTime=qSetting->value("timer/dev_snap_syn_timer").toInt();
    uint64 face_frequency=qSetting->value("devices/face_frequency").toULongLong();

    cameraHandle->initSdkRealTimeDevSnapSyn(sdk_handle,synTime,face_frequency);
    int seTime=qSetting->value("timer/semaphore_time").toInt();
    cameraHandle->setTimeoutMs(seTime);
    cameraHandle->initParkingSpaceInfo(areas);
    Common & instace= Common::getInstance();

    QString key =parameter.sDevId + ":" + QString::number(parameter.nDevPort);
    faceDetectionParkingPushs[key]= cameraHandle;
    HttpService httpService(parameter.httpUrl);
    vides_data::response *res=httpService.httpFindGb28181Config(parameter.sSn);
    if(res->code!=0){
        qInfo()<<"请求摄像头gb28181配置失败";
        instace.deleteObj(res);
        return;
    }
    vides_data::responseGb28181 *gb281 = reinterpret_cast<vides_data::responseGb28181*>(res->data);
    QString stGb281;
    bool re= iniWorkSpVMn(gb281,stGb281,parameter.sSn);
    if(!re){
        QByteArray bGb =stGb281.toUtf8();
        const char* cGb=bGb.data();
        cameraHandle->sdkDevSpvMn(cGb);
    }
    instace.deleteObj(gb281);
    instace.deleteObj(res);
}

void MainWindow::setVideoPath(int flag, const QString& path) {
    Common& instance = Common::getInstance();
    switch (flag) {
    case 0x00:
        instance.setVideoOut(path);
        break;
    case 0x01:
        instance.setVideoDownload(path);
        break;
    case 0x02:
        instance.setImages(path);
        break;
    default:
        // 处理未知的标志值
        break;
    }
}
void MainWindow::createDirectory(int flag,const QString& dirName, const QString& successMsg, const QString& failureMsg) {
    QDir directory;
    if (directory.exists(dirName)) {
        qDebug() << successMsg << "目录已存在";
        setVideoPath(flag, directory.absoluteFilePath(dirName));
    } else {
        if (directory.mkdir(dirName)) {
            qDebug() << successMsg << "目录创建成功";
            setVideoPath(flag, directory.absoluteFilePath(dirName));
        } else {
            qDebug() << failureMsg << "目录创建失败";
        }
    }
}

void MainWindow::initCommon(){
    createDirectory(0x01,"frame_images", "目录创建成功", "目录创建失败");
    createDirectory(0x00,"frame_video", "创建视频目录成功", "视频目录创建失败");
    createDirectory(0x02,"images", "图片目录创建成功", "图片目录创建失败");
    float carConfidenceMax=qSetting->value("devices/carConfidenceMax").toFloat();
    float carConfidenceMin=qSetting->value("devices/carConfidenceMin").toFloat();
    Common& instance = Common::getInstance();
    instance.setCarConfidenceMax(carConfidenceMax);
    instance.setCarConfidenceMin(carConfidenceMin);
}

MainWindow::~MainWindow()
{
    //delete ui;
    Common & instace= Common::getInstance();
    instace.deleteObj(qSetting);
    instace.deleteObj(deleteLogFileTimer);
    instace.deleteObj(deleteFrameFileTimer);
    instace.deleteObj(dePermissionSynTimer);
    
    for(auto iter = faceDetectionParkingPushs.begin(); iter != faceDetectionParkingPushs.end(); ++iter) {
        instace.deleteObj( iter->second);
    }
    // 清空 handleMap
    faceDetectionParkingPushs.clear();
    
    LogHandler::Get().uninstallMessageHandler();
    
}

void MainWindow::deleteMkvFileTimer(){
    Common& instance = Common::getInstance();
    QDir dir(instance.getVideoOut());
    QStringList filters;
    filters << "*.mp4" << "*.avi" << "*.jpg" << "*.mkv"; // 根据需要添加其他视频格式
    dir.setNameFilters(filters);
    QFileInfoList fileList = dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot);
    foreach (QFileInfo fileInfo, fileList) {
        QDateTime createTime = fileInfo.metadataChangeTime();
        QDateTime now = QDateTime::currentDateTime();
        if (createTime.secsTo(now) > 24 * 3600) { // 超过72小时
            if (!QFile::remove(fileInfo.absoluteFilePath())) {
                qInfo() << "Failed to delete file:" << fileInfo.fileName();
            }
        }
    }
    
}

void MainWindow::deleteLogFile(){
    QDateTime now = QDateTime::currentDateTime();
    QDir  logDir("log");
    // 前3天
    QDateTime dateTime1 = now.addDays(-3);
    QDateTime dateTime2;
    
    QString logPath = logDir.absoluteFilePath(""); // 日志的路径
    
    QDir dir(logPath);
    
    QStringList filename ;
    filename << "*.log";//可叠加，可使用通配符筛选
    
    QFileInfoList fileList = dir.entryInfoList(filename);
    foreach (QFileInfo f, fileList) {
        // "."和".."跳过
        if (f.baseName() == "" || f.baseName()=="today" )
            continue;
        
        dateTime2 = QDateTime::fromString(f.baseName(), "yyyy-MM-dd");
        if (dateTime2 < dateTime1) { // 只要日志时间小于前3天的时间就删除
            dir.remove(f.absoluteFilePath());
        }
    }
}

void MainWindow::initFaceFaceRecognition() {
    
    qSetting->beginGroup("cloudImageMap");
    
    QStringList keys = qSetting->childKeys();
    
    foreach(QString key, keys) {
        QString value = qSetting->value(key).toString();
        cloudImageMap[key]=value;
    }
    qSetting->endGroup();
    qSetting->beginGroup("localImageMap");
    QStringList lokeys = qSetting->childKeys();
    
    foreach(QString lk, lokeys) {
        // 获取键对应的值
        QString value = qSetting->value(lk).toString();
        localImageMap[lk]=value;
    }
    qSetting->endGroup();
}
