#include "localmodelconfigwidget.h"

LocalModelConfigWidget::LocalModelConfigWidget(QWidget *parent) : QDialog(parent)
{
    //初始化布局
    initLayout();
    //初始化本地模型能力
    loadNlpModelConfig();
    loadOtherModelConfig();
    //初始化信号槽
    initConnect();
}

void LocalModelConfigWidget::initLayout()
{
    this->setFixedSize(540,610);
    this->setWindowTitle(tr("Local Model"));

    m_mainVLayout = new QVBoxLayout();

    initModelTitleLayout();
    initModellayout();

    m_mainVLayout->setStretch(0,2);
    m_mainVLayout->setStretch(1,8);
    this->setLayout(m_mainVLayout);
}

void LocalModelConfigWidget::initModelTitleLayout()
{
    // 创建背景 Widget
    QWidget* backgroundWidget = new QWidget(this);
    backgroundWidget->setAccessibleName("kylin-ai-subsystem-modelconfig_QWidget_backgroundWidget");
    backgroundWidget->setFixedHeight(72);
    backgroundWidget->setStyleSheet("background-image: url(:/res/icon/background.svg); background-repeat: no-repeat; background-position: center;");

    // 创建水平布局
    m_titleHLayout = new QHBoxLayout(backgroundWidget);

    // 左侧图标布局
    m_vLeftLayout = new QVBoxLayout();
    m_iconLabel = new QLabel(backgroundWidget);
    m_iconLabel->setAccessibleName("kylin-ai-subsystem-modelconfig_QLabel_m_iconLabel");
    QPixmap iconPixmap(":/res/icon/ukui-local-model-symbolic.svg"); // 替换成本地模型图标
    if(!iconPixmap.isNull())
    {
        iconPixmap = iconPixmap.scaled(24, 24, Qt::KeepAspectRatio, Qt::SmoothTransformation);
        m_iconLabel->setPixmap(iconPixmap);
    }
    m_iconLabel->setFixedSize(24, 24);
    m_iconLabel->setStyleSheet("background: transparent;");
    m_iconLabel->setAlignment(Qt::AlignCenter);
    m_iconLabel->setContentsMargins(16, 24, 0, 24);
    m_vLeftLayout->setContentsMargins(16, 0, 0, 0);
    m_vLeftLayout->addWidget(m_iconLabel);

    // 右侧文本布局
    m_localHLayout = new QVBoxLayout();
    m_localLabel = new QLabel(backgroundWidget);
    m_localLabel->setAccessibleName("kylin-ai-subsystem-modelconfig_QLabel_m_localLabel");
    m_localLabel->setFixedSize(216, 24);
    m_localLabel->setText(tr("Local Model"));
    QFont localFont;
    localFont.setBold(true);
    m_localLabel->setFont(localFont);
    m_localLabel->setStyleSheet("color: #3790FA; background: transparent;");

    m_descripLabel = new kdk::KLabel(backgroundWidget);
    m_descripLabel->setAccessibleName("kylin-ai-subsystem-modelconfig_QLabel_m_descripLabel");
    m_descripLabel->setFixedSize(450, 20);
    m_descripLabel->setText(tr("Installed on local equipment, it can run without network"));
    QFont localDescripFont;
    localDescripFont.setPointSize(localFont.pointSize() - 2);
    m_descripLabel->setFont(localDescripFont);
    m_descripLabel->setFontColor("#3790FA");
    m_descripLabel->setStyleSheet("background: transparent;");

    m_localHLayout->addWidget(m_localLabel);
    m_localHLayout->addWidget(m_descripLabel);
    m_localHLayout->setContentsMargins(0, 4, 232, 8);

    // 组合布局
    m_titleHLayout->addLayout(m_vLeftLayout);
    m_titleHLayout->addLayout(m_localHLayout);

    // 添加到主垂直布局
    m_mainVLayout->addWidget(backgroundWidget);
}

void LocalModelConfigWidget::initModellayout()
{
    m_baseVLayout = new QVBoxLayout(this);
    m_baseVLayout->setContentsMargins(0, 0, 0, 0);

    // NLP大语言模型
    m_nlpWidget = new QWidget(this);
    m_nlpWidget->setAccessibleName("kylin-ai-subsystem-modelconfig_QWidget_m_nlpWidget");
    m_nlpVLayout = new QVBoxLayout;
    m_nlpVLayout->setContentsMargins(0, 0, 0, 0);
    m_nlpHLayout = new QHBoxLayout;
    m_nlpHLayout->setContentsMargins(16, 0, 16, 0);

    m_nlpLabelHLayout = new QHBoxLayout;

    // NLP标题
    QFont font;
    font.setBold(true); // 设置字体加粗
    m_nlpLabel = new QLabel(m_nlpWidget);
    m_nlpLabel->setAccessibleName("kylin-ai-subsystem-modelconfig_QLabel_m_nlpLabel");
    m_nlpLabel->setText(tr("NLP Model"));
    m_nlpLabel->setFont(font);

    // hover显示提示的按钮
    m_tipButton = new QPushButton(m_nlpWidget);
    m_tipButton->setAccessibleName("kylin-ai-subsystem-modelconfig_QPushButton_tipButton");
    m_tipButton->setIcon(QIcon::fromTheme("help-about-symbolic"));
    m_tipButton->setFixedSize(16, 16);
    m_tipButton->setFocusPolicy(Qt::NoFocus);
    m_tipButton->setStyleSheet("QPushButton {" "border: none;"
                                               "background-color: transparent;"
                                               "padding: 0px;" "}");
    m_tipButton->setToolTip(tr("After downloading and installing, you need to log out for it to take effect"));

    m_nlpLabelHLayout->addWidget(m_nlpLabel);
    m_nlpLabelHLayout->addWidget(m_tipButton);
    m_nlpLabelHLayout->addStretch(0);

    // NLP描述
    m_nlpDescLabel = new kdk::KLabel(m_nlpWidget);
    m_nlpDescLabel->setAccessibleName("kylin-ai-subsystem-modelconfig_kdk::KLabel_m_nlpDescLabel");
    m_nlpDescLabel->setText(tr("Processing and generating text, such as understanding text and answering questions"));
    m_nlpDescLabel->setMaximumWidth(320);
    m_nlpDescLabel->setFontColor("#808080");

    // 标题和描述放入布局
    m_nlpDescVLayout  = new QVBoxLayout();
    m_nlpDescVLayout->setSpacing(0);
    m_nlpDescVLayout->setContentsMargins(0, 0, 0, 0);
    m_nlpDescVLayout->addLayout(m_nlpLabelHLayout);
    m_nlpDescVLayout->addWidget(m_nlpDescLabel);

    // 安装按钮
    m_installButton = new KBorderlessButton(m_nlpWidget);
    m_installButton->setAccessibleName("kylin-ai-subsystem-modelconfig_KBorderlessButton_installButton");
    m_installButton->setIcon(QIcon::fromTheme("browser-download-symbolic"));
    m_installButton->setIconSize(QSize(16, 16));
    m_installButton->setText(tr("Install"));
    m_installButton->setVisible(false);

    // 更新/卸载按钮
    m_updateOrUninstallBtn = new KBorderlessButton(m_nlpWidget);
    m_updateOrUninstallBtn->setAccessibleName("kylin-ai-subsystem-modelconfig_KBorderlessButton_updateAndUninstallBtn");
    m_updateOrUninstallBtn->setIcon(QIcon::fromTheme("software-update-available-symbolic"));
    m_updateOrUninstallBtn->setIconSize(QSize(16, 16));
    m_updateOrUninstallBtn->setText(tr("Update/Uninstall"));
    m_updateOrUninstallBtn->setVisible(false);

    // 已配置模型
    m_nlpLocalModelGroup = new SettingGroup(m_nlpWidget);
    m_nlpLocalModelGroup->setAccessibleName("kylin-ai-subsystem-modelconfig_SettingGroup_m_nlpLocalModelGroup");

    m_nlpHLayout->addLayout(m_nlpDescVLayout);
    m_nlpHLayout->addStretch();
    m_nlpHLayout->addWidget(m_installButton);
    m_nlpHLayout->addWidget(m_updateOrUninstallBtn);

    m_nlpVLayout->addLayout(m_nlpHLayout);
    m_nlpVLayout->addWidget(m_nlpLocalModelGroup);

    // 系统内置模型 图像识别、向量化、语音处理等其他系统运行所需的模型
    m_otherVLayout = new QVBoxLayout();
    m_otherVLayout->setContentsMargins(0, 0, 0, 0);
    m_otherDescVLayout = new QVBoxLayout();
    m_otherDescVLayout->setSpacing(0);
    m_otherDescVLayout->setContentsMargins(16, 0, 16, 0);

    m_otherLabel = new QLabel(m_nlpWidget);
    m_otherLabel->setAccessibleName("kylin-ai-subsystem-modelconfig_QLabel_m_otherLabel");
    m_otherLabel->setText(tr("Built in model of the system"));
    m_otherLabel->setFont(font);

    m_otherDescLabel = new kdk::KLabel(m_nlpWidget);
    m_otherDescLabel->setAccessibleName("kylin-ai-subsystem-modelconfig_kdk::KLabel_m_otherDescLabel");
    m_otherDescLabel->setText(tr("The system has built-in models for image recognition, vectorization, speech processing, "
                                 "and other necessary models for system operation"));
    m_otherDescLabel->setFixedWidth(450);
    m_otherDescLabel->setFontColor("#808080");

    m_otherDescVLayout->addWidget(m_otherLabel);
    m_otherDescVLayout->addWidget(m_otherDescLabel);

    m_otherModelGroup = new SettingGroup(m_nlpWidget);
    m_otherModelGroup->setAccessibleName("kylin-ai-subsystem-modelconfig_SettingGroup_m_otherModelGroup");
    m_otherVLayout->addLayout(m_otherDescVLayout);
    m_otherVLayout->addWidget(m_otherModelGroup);

    m_baseVLayout->addLayout(m_nlpVLayout);
    m_baseVLayout->addLayout(m_otherVLayout);
    m_nlpWidget->setLayout(m_baseVLayout);

    // VISION视觉模型
    m_visionWidget = new QWidget;
    m_visionWidget->setAccessibleName("kylin-ai-subsystem-modelconfig_QWidget_m_visionWidget");
    m_visionVLayout = new QVBoxLayout;
    m_visionVLayout->setContentsMargins(0, 0, 0, 0);
    m_visionHLayout = new QHBoxLayout;
    m_visionHLayout->setContentsMargins(16, 0, 16, 0);

    // VISION标题
    m_visionLabel = new QLabel;
    m_visionLabel->setAccessibleName("kylin-ai-subsystem-modelconfig_QLabel_m_visionLabel");
//    m_visionLabel->setText(tr("Visual Model"));
    m_visionLabel->setFont(font);

    // VISION描述
//    m_visionDescrLabel = new kdk::KLabel;
//    m_visionDescrLabel->setAccessibleName("kylin-ai-subsystem-modelconfig_kdk::KLabel_m_visionDescrLabel");
//    m_visionDescrLabel->setText(tr("Processing and generating images, such as recognizing objects and analyzing scenes"));
//    m_visionDescrLabel->setFixedWidth(400);
//    m_visionDescrLabel->setStyleSheet("color: #808080;");

    // 标题和描述放入布局
    m_visionDescVLayout  = new QVBoxLayout();
    m_visionDescVLayout->addWidget(m_visionLabel);
    m_visionDescVLayout->addWidget(m_visionDescrLabel);

    // 已配置模型
    m_visionLocalModelGroup = new SettingGroup;
    m_visionLocalModelGroup->setAccessibleName("kylin-ai-subsystem-modelconfig_SettingGroup_m_visionLocalModelGroup");
    m_visionHLayout->addLayout(m_visionDescVLayout);
    m_visionHLayout->addStretch();

    m_visionVLayout->addLayout(m_visionHLayout);
    m_visionVLayout->addWidget(m_visionLocalModelGroup);

    m_visionWidget->setLayout(m_visionVLayout);

    // SPEECH语音模型
    m_speechWidget = new QWidget;
    m_speechWidget->setAccessibleName("kylin-ai-subsystem-modelconfig_QWidget_m_speechWidget");
    m_speechVLayout = new QVBoxLayout;
    m_speechVLayout->setContentsMargins(0, 0, 0, 0);
    m_speechHLayout = new QHBoxLayout;
    m_speechHLayout->setContentsMargins(16, 0, 16, 0);

    // SPEECH标题
    m_speechLabel = new QLabel;
    m_speechLabel->setAccessibleName("kylin-ai-subsystem-modelconfig_QLabel_m_speechLabel");
//    m_speechLabel->setText(tr("Speech Model"));
    m_speechLabel->setFont(font);

    // SPEECH描述
//    m_speechDescLabel = new kdk::KLabel;
//    m_speechDescLabel->setAccessibleName("kylin-ai-subsystem-modelconfig_kdk::KLabel_m_speechDescLabel");
//    m_speechDescLabel->setText(tr("Processing sound and speech, such as recognizing speech and synthesizing speech"));
//    m_speechDescLabel->setFixedWidth(400);
//    m_speechDescLabel->setStyleSheet("color: #808080;");

    // 标题和描述放入布局
    m_speechDescVlayout  = new QVBoxLayout();
    m_speechDescVlayout->addWidget(m_speechLabel);
    m_speechDescVlayout->addWidget(m_speechDescLabel);

    // 已配置模型
    m_speechLocalModelGroup = new SettingGroup;
    m_speechLocalModelGroup->setAccessibleName("kylin-ai-subsystem-modelconfig_SettingGroup_m_speechLocalModelGroup");
    m_speechHLayout->addLayout(m_speechDescVlayout);
    m_speechHLayout->addStretch();

    m_speechVLayout->addLayout(m_speechHLayout);
    m_speechVLayout->addWidget(m_speechLocalModelGroup);

    m_speechWidget->setLayout(m_speechVLayout);

    // 滚动区域
    m_scrollVLayout = new QVBoxLayout;
    m_scrollVLayout->setContentsMargins(16, 20, 16, 0);
    m_scrollVLayout->addWidget(m_nlpWidget);
    m_scrollVLayout->addWidget(m_visionWidget);
    m_scrollVLayout->addWidget(m_speechWidget);
    m_scrollVLayout->addStretch();

    m_scrollWidget = new QWidget;
    m_scrollWidget->setAccessibleName("kylin-ai-subsystem-modelconfig_QWidget_m_scrollWidget");
    m_scrollWidget->setContentsMargins(0, 0, 0, 0);
    m_scrollWidget->setLayout(m_scrollVLayout);

    m_scrollArea = new QScrollArea(this);
    m_scrollArea->setAccessibleName("kylin-ai-subsystem-modelconfig_QScrollArea_m_scrollArea");
    m_scrollArea->setFixedHeight(404);
    m_scrollArea->setWidgetResizable(true);
    m_scrollArea->setFrameStyle(QFrame::NoFrame); // 无边框
    m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // 不显示水平滚动条
    m_scrollArea->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu);
    m_scrollArea->verticalScrollBar()->setProperty("drawScrollBarGroove", false);

    m_scrollArea->setWidget(m_scrollWidget);
    m_mainVLayout->addWidget(m_scrollArea);

    m_confirmLocalButton = new QPushButton(tr("OK"), this);
    m_confirmLocalButton->setAccessibleName("kylin-ai-subsystem-modelconfig_QPushButton_m_confirmLocalButton");
    m_confirmLocalButton->setProperty("isImportant", true);
    m_confirmLocalButtoLayout = new QHBoxLayout();
    m_confirmLocalButtoLayout->setContentsMargins(0, 0, 24, 24);
    m_confirmLocalButtoLayout->addStretch();
    m_confirmLocalButtoLayout->addWidget(m_confirmLocalButton);
    m_mainVLayout->addStretch();
    m_mainVLayout->addLayout(m_confirmLocalButtoLayout);
}

ModelStatus LocalModelConfigWidget::getModelStatus(QString modelName)
{
    ModelConfig mc;
    ModelStatus ret = mc.getModelStatus(modelName.toStdString());
    KyInfo() << QString("ModelStatus = %0").arg((qint32)ret);
    return ret;
}

void LocalModelConfigWidget::onEditModelItem(AiCapability capability, QString modelName)
{

}

void LocalModelConfigWidget::onDeleteModelItem(AiCapability capability, QString modelName)
{
    bool isCheckSelected = checkModelSelection(capability, modelName);
    if (isCheckSelected)
    {
        // 删除当前选中模型
        if ((capability == AiCapability::Nlp && (getModelStatus(modelName) == ModelStatus::Running))
                || (capability == AiCapability::Nlp && (getModelStatus(modelName) == ModelStatus::Running))
                || (capability == AiCapability::Vision && (getModelStatus(modelName) == ModelStatus::Running))
                || (capability == AiCapability::Speech && (getModelStatus(modelName) == ModelStatus::Running))
                || (capability == AiCapability::Speech && (getModelStatus(modelName) == ModelStatus::Running))
                || (capability == AiCapability::Speech && (getModelStatus(modelName) == ModelStatus::Running))) {
            // NLP or VISION or SPEECH 正在使用，重试弹窗
            KyInfo() << "正在使用" << static_cast<int>(capability) << modelName;
            bool canProceed = showModelInUseMessage(this);
            if (canProceed == true) {
                onDeleteModelItem(capability, modelName);
            } else {
                KyInfo() << "取消本次操作";
                return;
            }
        } else {
            // 未使用，确认弹窗
            bool canProceed = showConfirmMessage(this);
            if (canProceed == true) {
                bool ret = clearModelMultiAuths(capability, modelName);
                if (ret == true) {
                    deleteModelItem(capability,  modelName);
                    KyInfo() << modelName << " 验证信息clear成功";
                } else {
                    showErrorMessage(tr("Failed to delete model"), this);
                    KyInfo() << modelName << " 验证信息clear失败, 删除失败";
                }
            } else {
                KyInfo() << "取消本次操作";
                return;
            }
       }
    } else {
        // 删除非选中模型，确认弹窗
        bool canProceed = showConfirmMessage(this);
        if (canProceed == true) {
            ModelConfig mc;
            bool ret = mc.clearModelAuthentications(modelName.toStdString());
            if (ret == true) {
                deleteModelItem(capability,  modelName);
                KyInfo() << modelName << " 验证信息clear成功";
            } else {
                showErrorMessage(tr("Failed to delete model"), this);
                KyInfo() << modelName << " 验证信息clear失败, 删除失败";
            }
        } else {
            KyInfo() << "取消本次操作";
            return;
        }
    }
}

bool LocalModelConfigWidget::eventFilter(QObject *watched, QEvent *event)
{
    // 模型配置
    LocalModelItem *clickedModelItem = qobject_cast<LocalModelItem*>(watched);

    if (clickedModelItem) {

        if (event->type() == QEvent::MouseButtonRelease) {

            QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);

            if (mouseEvent->button() == Qt::LeftButton) { // 判断左键
               // 切换模型
                clickLocalModel(clickedModelItem->getAICapability(), clickedModelItem->getModelName());
                return true;
            }
        }
    }

    return QWidget::eventFilter(watched,event);
}

void LocalModelConfigWidget::closeEvent(QCloseEvent *event)
{
    bool isdownloading = ModelDownload::getInstance()->getDownloadingStatus();
    KyInfo() << " close event -----1----:current model is downloading :" << isdownloading;
    //检查是否正在初始化下载阶段
    bool isStartDownloading = ModelDownload::getInstance()->getStartDownloadingStatus();
    KyInfo() << " close event -----2----:current model is start downloading:" << isStartDownloading;
    //判断当前是否正在安装中，正在安装中则提示用户是否退出
    bool isInstalling = ModelDownload::getInstance()->getCurrentInstallStatus();
    KyInfo() << " close event -----3----:current  model is installing:" << isInstalling;

    //非正在下载状态则直接关闭界面
    if(isdownloading == false && isStartDownloading == false && isInstalling == false){
        event->accept();
        return;
    }else {
        //正在初始化安装中
        if(isStartDownloading)
        {
            //正在初始化下载过程中弹出二次确认窗口
            QMessageBox *msgBox = new QMessageBox(this);
            msgBox->setIcon(QMessageBox::Question);
            // 标题加粗并为黑色字体（使用 HTML）
            QString title = "<b><font color='black'>" + tr("Are you sure you want to exit?") + "</font></b>";
            msgBox->setText(title);
            // 说明文字也设为黑色
            QString infoText = "<font color='black'>" + tr("The model is currently being installed, exiting may result in installation failure. Are you sure you want to exit?") + "</font>";
            msgBox->setInformativeText(infoText);
            QPushButton *cancelButton = msgBox->addButton(tr("Cancel"), QMessageBox::RejectRole);
            QPushButton *quitButton = msgBox->addButton(tr("Quit"), QMessageBox::AcceptRole);
            connect(msgBox,&QMessageBox::finished,this,[=](){
               msgBox->close();
               event->ignore();
               return;
            });
            connect(quitButton,&QPushButton::clicked,this,[=](){
                bool cancelFlag = ModelDownload::getInstance()->cancelDownloading();
                if(cancelFlag)
                {
                    event->accept();
                    this->hide();
                    return;
                }
                else{
                    event->ignore();
                    return;
                }
            });
            connect(cancelButton,&QPushButton::clicked,this,[=](){
               event->ignore();
               return;
            });
            msgBox->setDefaultButton(cancelButton);
            msgBox->exec();
            }
        //正在安装中
        else if(isInstalling)
        {
            QMessageBox *msgBox = new QMessageBox(this);
            msgBox->setIcon(QMessageBox::Question);
            // 标题加粗并为黑色字体（使用 HTML）
            QString title = "<b><font color='black'>" + tr("Exit current window?") + "</font></b>";
            msgBox->setText(title);
            QString infoText = "<font color='black'>" + tr("The model installation will continue to run in the background. A restart is required for the changes to take effect once completed.") + "</font>";
            msgBox->setInformativeText(infoText);

            QPushButton *cancelButton = msgBox->addButton(tr("Cancel"), QMessageBox::RejectRole);
            QPushButton *quitButton = msgBox->addButton(tr("Quit"), QMessageBox::AcceptRole);
            connect(msgBox,&QMessageBox::finished,this,[=](){
                msgBox->close();
                event->ignore();
                return;
            });
            connect(quitButton,&QPushButton::clicked,this,[=](){
                event->accept();
                this->hide();
                return;
            });
            connect(cancelButton,&QPushButton::clicked,this,[=](){
               event->ignore();
               return;
            });
            msgBox->setDefaultButton(quitButton);
            msgBox->exec();

        }
        else if(isdownloading) {
        //正在下载过程中则弹出二次确认窗口
        QMessageBox *msgBox = new QMessageBox(this);
        msgBox->setIcon(QMessageBox::Question);
        // 标题加粗并为黑色字体（使用 HTML）
        QString title = "<b><font color='black'>" + tr("Are you sure you want to exit?") + "</font></b>";
        msgBox->setText(title);
        // 说明文字也设为黑色
        QString infoText = "<font color='black'>" + tr("The model is currently being installed, exiting may result in installation failure. Are you sure you want to exit?") + "</font>";
        msgBox->setInformativeText(infoText);
        QPushButton *cancelButton = msgBox->addButton(tr("Cancel"), QMessageBox::RejectRole);
        QPushButton *quitButton = msgBox->addButton(tr("Quit"), QMessageBox::AcceptRole);
        connect(msgBox,&QMessageBox::finished,this,[=](){
           msgBox->close();
           event->ignore();
           return;
        });
        connect(quitButton,&QPushButton::clicked,this,[=](){
            bool cancelFlag = ModelDownload::getInstance()->cancelDownloading();
            if(cancelFlag)
            {
                event->accept();
                this->hide();
                return;
            }
            else{
                event->ignore();
                return;
            }
        });
        connect(cancelButton,&QPushButton::clicked,this,[=](){
           event->ignore();
           return;
        });
        msgBox->setDefaultButton(cancelButton);
        msgBox->exec();
        }

        }
}

void LocalModelConfigWidget::loadNlpModelConfig() {
    ModelConfig mc;
    std::string curNlpModelName = mc.getCurrentModelName(AiCapability::Nlp, DeployType::Ondevice);

    bool isExistLocalModel = false;
    const auto models = mc.getExtendedModels(AiCapability::Nlp);
    for (const auto &model : models) {
        if(model.deployType != DeployType:: Ondevice) {
            continue;
        }

        UkccFrame *itemFrame = new UkccFrame;
        itemFrame->setAccessibleName("kylin-ai-subsystem-modelconfig_UkccFrame_itemFrame");
        itemFrame->setMinimumWidth(496);
        itemFrame->setMaximumWidth(496);
        itemFrame->setFixedHeight(56);
        itemFrame->installEventFilter(this);
        QHBoxLayout *layItem = new QHBoxLayout(itemFrame);
        layItem->setContentsMargins(0, 0, 0, 0);

        PublicLocalModel publicLocalModel;
        publicLocalModel.capability = model.capability;
        publicLocalModel.vendor = QString::fromStdString(model.vendor);
        publicLocalModel.modelName = QString::fromStdString(model.modelName);
        publicLocalModel.multiAuths  = mc.getModelAuthentications(model.modelName);
        publicLocalModel.debName =  QString::fromStdString(model.debName);

        LocalModelItem *item = new LocalModelItem(publicLocalModel, this);
        item->setAccessibleName("kylin-ai-subsystem-modelconfig_LocalModelItem_item");
        item->installEventFilter(this);

        layItem->addWidget(item);
        isExistLocalModel = true;

        m_nlpLocalModelGroup->addWidget(itemFrame);
        m_nlpLocalModelItemMap[publicLocalModel.modelName] = item;

        if (model.modelName == curNlpModelName) {
            item->showSelectedIcon(true);
        }
    }

    isExistLocalModel ? m_updateOrUninstallBtn->setVisible(true) :
                        m_installButton->setVisible(true);
}


void LocalModelConfigWidget::loadOtherModelConfig() {
    UkccFrame *itemFrame = new UkccFrame;
    itemFrame->setAccessibleName("kylin-ai-subsystem-modelconfig_UkccFrame_itemFrame");
    itemFrame->setMinimumWidth(496);
    itemFrame->setMaximumWidth(496);
    itemFrame->setFixedHeight(56);
    QHBoxLayout *layItem = new QHBoxLayout(itemFrame);
    layItem->setContentsMargins(16, 0, 0, 0);

    m_otherFrameLabelText = new QLabel();
    m_otherFrameLabelText->setAccessibleName("kylin-ai-subsystem-modelconfig_QLabel_frameLabel");
    m_otherFrameLabelText->setText(tr("Built in model group"));

    layItem->addWidget(m_otherFrameLabelText);
    m_otherModelGroup->addWidget(itemFrame);
}

void LocalModelConfigWidget::loadModelConfig()
{
    //清空modelmap所有组件
    m_nlpLocalModelMap.clear();
    m_visionLocalModelMap.clear();
    m_speechLocalModelMap.clear();

    m_nlpLocalModelItemMap.clear();
    m_visionLocalModelItemMap.clear();
    m_speechLocalModelItemMap.clear();

    m_nlpLocalModelGroup->removeAndDeleteAllWidget();
    m_visionLocalModelGroup->removeAndDeleteAllWidget();
    m_speechLocalModelGroup->removeAndDeleteAllWidget();
    m_nlpLocalModelMapUI.clear();
    m_visionLocalModelMapUI.clear();
    m_speechLocalModelMapUI.clear();
    ModelConfig mc;

    std::string nlpModel = mc.getCurrentModelName(AiCapability::Nlp, DeployType::Ondevice);
    std::string visionModel = mc.getCurrentModelName(AiCapability::Vision, DeployType::Ondevice);
    std::string speechModel = mc.getCurrentModelName(AiCapability::Speech, DeployType::Ondevice);

    KyInfo() << "loadModelConfig-------------getCurrentModelName" << "nlpModel" << QString::fromStdString(nlpModel) << "visionModel" << QString::fromStdString(visionModel) <<"speechModel" << QString::fromStdString(speechModel);

    nlpSelectedLocalModel = QString::fromStdString(nlpModel);
    visionSelectedLocalModel = QString::fromStdString(visionModel);
    speechSelectedLocalModel = QString::fromStdString(speechModel);

    for (auto capability : {AiCapability::Nlp, AiCapability::Vision, AiCapability::Speech}) {
        const auto models = mc.getExtendedModels(capability);
        for (const auto &model : models) {
            //过滤本地模型
            if(model.deployType == DeployType:: Ondevice)
            {
                PublicLocalModel publicLocalModel;
                publicLocalModel.capability = model.capability;
                publicLocalModel.vendor = QString::fromStdString(model.vendor);
                publicLocalModel.modelName = QString::fromStdString(model.modelName);
                publicLocalModel.multiAuths  = mc.getModelAuthentications(model.modelName);
                publicLocalModel.debName =  QString::fromStdString(model.debName);

                KyInfo() << "loadModelConfig模型名称" <<  QString::fromStdString(model.modelName);
                KyInfo() <<  "loadModelConfig厂商" << QString::fromStdString(model.vendor);
                KyInfo() << "loadModelConfig安装包名称" << QString::fromStdString(model.debName);
                for (const auto &authen : publicLocalModel.multiAuths) {
                    KyInfo() << "loadModelConfig配置项名称" << QString::fromStdString( authen.itemName);
                    for (const auto &au : authen.authentications) {
                        if (au.key == "appIdContinuous" || au.key == "apiKeyContinuous" || au.key == "secretKeyContinuous") {
                            if (au.value != "") {
                                continuousSelected = true;
                            }
                        } else if (au.key == "appIdRealTime" || au.key == "apiKeyRealTime") {
                            if (au.value != "") {
                                realtimeSelected = true;
                            }
                        }
                    }
                }

               switch (capability) {
               case AiCapability::Nlp:
                   loadModelItem(publicLocalModel, nlpSelectedLocalModel);
                   break;
               case AiCapability::Vision:
                   loadModelItem(publicLocalModel, visionSelectedLocalModel);
                   break;
               case AiCapability::Speech:
                   loadModelItem(publicLocalModel, speechSelectedLocalModel);
                   break;
               default:
                   break;
               }
            }

            }

    }

}

void LocalModelConfigWidget::initConnect()
{
    connect(m_confirmLocalButton, &QPushButton::clicked, this, [this](){
        this->close();
    });
    connect(m_installButton, &QPushButton::clicked,
            this, &LocalModelConfigWidget::openSoftwareStore);
    connect(m_updateOrUninstallBtn, &QPushButton::clicked,
            this, &LocalModelConfigWidget::openSoftwareStore);
}

void LocalModelConfigWidget::openSoftwareStore()
{
    //打开软件商店
    QString cmd = QString("/usr/bin/kylin-software-center -menuid=2 -tagid=716");
    QProcess::startDetached(cmd);
}

void LocalModelConfigWidget::addModelItem(PublicLocalModel model)
{
    UkccFrame *itemFrame = new UkccFrame;
    itemFrame->setAccessibleName("kylin-ai-subsystem-modelconfig_UkccFrame_itemFrame");
    itemFrame->setMinimumWidth(496);
    itemFrame->setMaximumWidth(496);
    itemFrame->setFixedHeight(56);
    itemFrame->setObjectName(model.modelName);
    QHBoxLayout *layItem = new QHBoxLayout(itemFrame);
    layItem->setContentsMargins(0, 0, 0, 0);

    QMessageBox::warning(nullptr,tr("Tips"),model.debName);

    LocalModelItem *item = new LocalModelItem(model);
    item->setAccessibleName("kylin-ai-subsystem-modelconfig_LocalModelItem_item");
    item->installEventFilter(this);
    connect(item, &LocalModelItem::sigEdit, this, &LocalModelConfigWidget::onEditModelItem);
    connect(item, &LocalModelItem::sigDelete, this, &LocalModelConfigWidget::onDeleteModelItem);

    layItem->addWidget(item);

    if (model.capability == AiCapability::Nlp)
    {
        m_nlpLocalModelMap[model.modelName] = model;
        m_nlpLocalModelItemMap[model.modelName] = item;
        m_nlpLocalModelMapUI[model.modelName] = itemFrame;
        m_nlpLocalModelGroup->addWidget(itemFrame);

        KyInfo() << "count:" <<m_nlpLocalModelMap.count()<< "modelName" << model.modelName;
        // 第一个添加的模型，设置为选中
        bool isModelInstalled = this->checkModelInstalled(model.capability,model.modelName);

        if (m_nlpLocalModelItemMap.count() == 1 && isModelInstalled) {
            item->showSelectedIcon(true);
            nlpSelectedLocalModel = model.modelName;
        }
    }
    else if (model.capability == AiCapability::Vision)
    {
        m_visionLocalModelMap[model.modelName] = model;
        m_visionLocalModelItemMap[model.modelName] = item;
        m_visionLocalModelMapUI[model.modelName] = itemFrame;
        m_visionLocalModelGroup->addWidget(itemFrame);

        // 第一个添加的模型，设置为选中
        if (m_visionLocalModelItemMap.count() == 1) {
            item->showSelectedIcon(true);
            visionSelectedLocalModel = model.modelName;
        }
    }
    else if (model.capability == AiCapability::Speech)
    {
        m_speechLocalModelMap[model.modelName] = model;
        m_speechLocalModelItemMap[model.modelName] = item;
        m_speechLocalModelMapUI[model.modelName] = itemFrame;
        m_speechLocalModelGroup->addWidget(itemFrame);

        // 第一个添加的模型，设置为选中
        if (m_speechLocalModelItemMap.count() == 1) {
            item->showSelectedIcon(true);
            speechSelectedLocalModel = model.modelName;
        }
    }
}

void LocalModelConfigWidget::loadModelItem(PublicLocalModel model, QString curSelectedName)
{
    ModelConfig mc;
    std::vector<MultiAuthentication> multiAuths  = mc.getModelAuthentications(model.modelName.toStdString());
    bool isValueEmpty = false;
    bool isContinuousValueEmpty = false;
    bool isRealtimeValueEmpty = false;

    for (const auto &authen : multiAuths) {
        for (const auto &au : authen.authentications) {
            if (au.key == "appIdRealTime" || au.key == "apiKeyRealTime") {
                if (au.value == "") {
                    isContinuousValueEmpty = true;
                }
            } else if (au.key == "appIdContinuous" || au.key == "apiKeyContinuous" || au.key == "secretKeyContinuous") {
                if (au.value == "") {
                    isRealtimeValueEmpty = true;
                }
            } else {
                if (au.value == "") {
                    isValueEmpty = true;
                }
            }
        }
    }

    if (model.modelName == "讯飞-语音大模型") {
        if (isContinuousValueEmpty && isRealtimeValueEmpty) {
            KyInfo() << model.modelName << "验证信息为空，不加载";
            return;
        }
    } else {
        if(isValueEmpty) {
           KyInfo() << model.modelName << "验证信息为空，不加载";
           return;
        }
    }

    UkccFrame *itemFrame = new UkccFrame;
    itemFrame->setAccessibleName("kylin-ai-subsystem-modelconfig_UkccFrame_itemFrame");
    itemFrame->setMinimumWidth(496);
    itemFrame->setMaximumWidth(496);
    itemFrame->setFixedHeight(56);
    itemFrame->setObjectName(model.modelName);
    QHBoxLayout *layItem = new QHBoxLayout(itemFrame);
    layItem->setContentsMargins(0, 0, 0, 0);

    LocalModelItem *item = new LocalModelItem(model,this);
    item->setAccessibleName("kylin-ai-subsystem-modelconfig_LocalModelItem_item");
    item->installEventFilter(this);
    connect(item, &LocalModelItem::sigEdit, this, &LocalModelConfigWidget::onEditModelItem);
    connect(item, &LocalModelItem::sigDelete, this, &LocalModelConfigWidget::onDeleteModelItem);

    layItem->addWidget(item);

    if (model.capability == AiCapability::Nlp )
    {
        m_nlpLocalModelMap[model.modelName] = model;
        m_nlpLocalModelItemMap[model.modelName] = item;
        m_nlpLocalModelMapUI[model.modelName] = itemFrame;
        m_nlpLocalModelGroup->addWidget(itemFrame);

        bool isModelInstalled = this->checkModelInstalled(model.capability,model.modelName);
        KyInfo() << "1111111111111111:" << model.modelName << curSelectedName << isModelInstalled;

        // 设置为选中
        if (model.modelName == curSelectedName && isModelInstalled) {
            item->showSelectedIcon(true);
            nlpSelectedLocalModel = model.modelName;
        }
        else {
            nlpSelectedLocalModel.clear();
        }
    }
    else if (model.capability == AiCapability::Vision)
    {
        m_visionLocalModelMap[model.modelName] = model;
        m_visionLocalModelItemMap[model.modelName] = item;
        m_visionLocalModelMapUI[model.modelName] = itemFrame;
        m_visionLocalModelGroup->addWidget(itemFrame);

        // 设置为选中
        if (model.modelName == curSelectedName) {
            item->showSelectedIcon(true);
            visionSelectedLocalModel = model.modelName;
        }
    }
    else if (model.capability == AiCapability::Speech)
    {
        m_speechLocalModelMap[model.modelName] = model;
        m_speechLocalModelItemMap[model.modelName] = item;
        m_speechLocalModelMapUI[model.modelName] = itemFrame;
        m_speechLocalModelGroup->addWidget(itemFrame);

        // 设置为选中
        if (model.modelName == curSelectedName) {
            item->showSelectedIcon(true);
            speechSelectedLocalModel = model.modelName;
        }
    }
}

void LocalModelConfigWidget::deleteModelItem(AiCapability capability, QString modelName)
{
    ModelConfig mc;
    QString curModelName = QString::fromStdString(mc.getCurrentModelName(capability,DeployType::Ondevice));
    bool isCheckSelected = checkModelSelection(capability, modelName);
    //KyInfo() << "currentmodelname" << curModelName << "要删除的modelname" << modelName << "isCheckSelected" << isCheckSelected;

    if (capability == AiCapability::Nlp)
    {
        m_nlpLocalModelMap.remove(modelName);
        m_nlpLocalModelItemMap.remove(modelName);
        m_nlpLocalModelGroup->removeWidget(m_nlpLocalModelMapUI[modelName]);
        m_nlpLocalModelMapUI.remove(modelName);

        // 如果删除选中模型,需重新设置currentmodelname
        if(curModelName == modelName || isCheckSelected)
        {
            if (m_nlpLocalModelItemMap.count() > 0) {
                // 删除后，设置剩下模型中的第一个为选中
                auto remainingModelItems = m_nlpLocalModelItemMap.values();
                QString firstModelName = remainingModelItems.first()->getModelName();

                bool ret = setSelectLocalModelName(capability, DeployType::Ondevice, firstModelName); // set sdk
                if (ret == true) {
                    switchModelItem(remainingModelItems.first()->getAICapability(), remainingModelItems.first()->getModelName());
                    KyInfo() << modelName << " 设置为选中模型成功";
                } else {
                    showErrorMessage(tr("Model setup failed"), this);
                    KyInfo() << modelName << " 设置为选中模型失败";
                    return;
                }

            } else {
                // 删除后无模型
                KyInfo() << " nlpModelItemMap为空";
                nlpSelectedLocalModel = "";
            }
        }
    }
    else if (capability == AiCapability::Vision)
    {
        m_visionLocalModelMap.remove(modelName);
        m_visionLocalModelItemMap.remove(modelName);
        m_visionLocalModelGroup->removeWidget(m_visionLocalModelMapUI[modelName]);
        m_visionLocalModelMapUI.remove(modelName);

        // 如果删除选中模型,需重新设置currentmodelname
        if(curModelName == modelName || isCheckSelected)
        {
            if (m_visionLocalModelItemMap.count() > 0) {
                // 删除后，设置剩下模型中的第一个为选中
                auto remainingModelItems = m_visionLocalModelItemMap.values();
                QString firstModelName = remainingModelItems.first()->getModelName();

                bool ret = setSelectLocalModelName(capability, DeployType::Ondevice, firstModelName); // set sdk
                if (ret == true) {
                    switchModelItem(remainingModelItems.first()->getAICapability(), remainingModelItems.first()->getModelName());
                    KyInfo() << modelName << " 设置为选中模型成功";
                } else {
                    showErrorMessage(tr("Model setup failed"), this);
                    KyInfo() << modelName << " 设置为选中模型失败";
                    return;
                }

            } else {
                // 删除后无模型
                KyInfo() << " visionModelItemMap为空";
                visionSelectedLocalModel = "";
            }
        }

    }
    else if (capability == AiCapability::Speech)
    {
        m_speechLocalModelMap.remove(modelName);
        m_speechLocalModelItemMap.remove(modelName);
        m_speechLocalModelGroup->removeWidget(m_speechLocalModelMapUI[modelName]);
        m_speechLocalModelMapUI.remove(modelName);

        // 如果删除选中模型,需重新设置currentmodelname
        if(curModelName == modelName || isCheckSelected)
        {
            if (m_speechLocalModelItemMap.count() > 0) {

                // 删除后，设置剩下模型中的第一个为选中
                auto remainingModelItems = m_speechLocalModelItemMap.values();
                QString firstModelName = remainingModelItems.first()->getModelName();

                bool ret = setSelectLocalModelName(capability, DeployType::Ondevice, firstModelName); // set sdk
                if (ret == true) {
                    switchModelItem(remainingModelItems.first()->getAICapability(), remainingModelItems.first()->getModelName());
                    KyInfo() << modelName << " 设置为选中模型成功";
                } else {
                    showErrorMessage(tr("Model setup failed"), this);
                    KyInfo() << modelName << " 设置为选中模型失败";
                    return;
                }

            } else {
                // 删除后无模型
                KyInfo() << " speechModelItemMap为空";
                speechSelectedLocalModel = "";
            }
        }
    }
}

void LocalModelConfigWidget::switchModelItem(AiCapability capability, QString modelName)
{
    QMap<QString, LocalModelItem*> *localModelItemMap = nullptr;

    if (capability == AiCapability::Nlp) {
        localModelItemMap = &m_nlpLocalModelItemMap;

    } else if (capability == AiCapability::Vision) {
        localModelItemMap = &m_visionLocalModelItemMap;

    } else if (capability == AiCapability::Speech) {
        localModelItemMap = &m_speechLocalModelItemMap;
    }

    if (localModelItemMap)
    {
        foreach (const auto& modelItemName, localModelItemMap->keys()) {
            LocalModelItem* modelItem = localModelItemMap->value(modelItemName);
            if (modelItem->getModelName() == modelName) {
                KyInfo() << "匹配成功，展示图标";
                modelItem->showSelectedIcon(true);

                if (capability == AiCapability::Nlp) {
                    nlpSelectedLocalModel = modelName;

                } else if (capability == AiCapability::Vision) {
                    visionSelectedLocalModel = modelName;

                } else if (capability == AiCapability::Speech) {
                    speechSelectedLocalModel = modelName;
                }

            } else {
                // 不匹配，隐藏图标
                KyInfo() << "不匹配，隐藏图标";
                modelItem->showSelectedIcon(false);
            }
        }
    }
}

bool LocalModelConfigWidget::setSelectLocalModelName(AiCapability capability, DeployType deployType, QString modelName)
{

    ModelConfig mc;
    bool ret2 = mc.setCurrentModelName(capability, deployType, modelName.toStdString());
    //bool isInstall = checkCurrentLocalModelInstall(kaglobal::ondeviceModelInstallPath) && modelName == "qwen_fastllm";
    //KyInfo() << "setSelectLocalModelName" << modelName;
    if ( ret2 == true )
    {
        KyInfo() << "setCurrentModelName success:"<< ret2 ;
    } else {
        KyInfo() << "setCurrentModelName failed:"<< ret2 ;
    }
    return ret2 ;
}

void LocalModelConfigWidget::editSelectLocalModel(PublicLocalModel model, bool isContinuousSelected, bool isRealTimeSelected, bool isValueChanged)
{

}

void LocalModelConfigWidget::clickLocalModel(AiCapability capability, QString modelName)
{
    //判断当前模型是否已选中
    bool ret = checkModelSelection(capability, modelName);
    if (ret == true) {
        return;
    } else {
        //如果模型正在使用
        if ((capability == AiCapability::Nlp &&  (getModelStatus(modelName) == ModelStatus::Running))
                || (capability == AiCapability::Nlp &&  (getModelStatus(modelName) == ModelStatus::Running))
                || (capability == AiCapability::Vision &&  (getModelStatus(modelName) == ModelStatus::Running))
                || (capability == AiCapability::Speech &&  (getModelStatus(modelName) == ModelStatus::Running))
                || (capability == AiCapability::Speech &&  (getModelStatus(modelName) == ModelStatus::Running))
                || (capability == AiCapability::Speech &&  (getModelStatus(modelName) == ModelStatus::Running))) {
            // NLP or VISION or SPEECH 正在使用
            KyInfo() << "正在使用" << static_cast<int>(capability);
            bool canProceed = showModelInUseMessage(this);
            if (canProceed == true) {
                clickLocalModel(capability, modelName);
            } else {
                 KyInfo() << "取消本次操作";
                return;
            }
          //当前模型未选中则进行切换
        } else {
            KyInfo() << "aaa:" << static_cast<int>(capability) << modelName;
            //判断当前模型是否已经安装可切换，否则直接返回
            bool ret = setSelectLocalModelName(capability, DeployType::Ondevice, modelName);
            if (ret == true) {
                switchModelItem(capability, modelName);
                KyInfo() << modelName << " 设置为选中模型成功";
            } else {
                showErrorMessage(tr("Model switching failed"),this);
                KyInfo() << modelName << " 设置为选中模型失败";
            }
        }

    }

}

bool LocalModelConfigWidget::clearModelMultiAuths(AiCapability capability, QString modelName)
{

}

bool LocalModelConfigWidget::checkModelSelection(AiCapability capability, QString modelName)
{
    if (capability == AiCapability::Nlp) {
        if (modelName == nlpSelectedLocalModel) {
            return true;
        } else {
            return false;
        }

    } else if (capability == AiCapability::Vision) {
        if (modelName == visionSelectedLocalModel) {
            return true;
        } else {
            return false;
        }

    } else if (capability == AiCapability::Speech) {
        if (modelName == speechSelectedLocalModel) {
            return true;
        } else {
            return false;
        }
    } else {
        return false;
    }
}

bool LocalModelConfigWidget::checkModelInstalled(AiCapability capability, QString modelName)
{
    PublicLocalModel model = m_nlpLocalModelMap.value(modelName);
    bool isInstalled = ModelDownload::getInstance()->isPkgInstalled(model.debName);
    return isInstalled;
}

void LocalModelConfigWidget::showNotInstallMessage(const QString &modelName)
{
    QMessageBox msgBox(nullptr);
    msgBox.setIcon(QMessageBox::Question);
    msgBox.setText(tr("Current model not install,you can use the model after install it."));

    QPushButton *cancelButton = msgBox.addButton(tr("Cancel"), QMessageBox::RejectRole);
    QPushButton *sureButton = msgBox.addButton(tr("Install Now"), QMessageBox::AcceptRole);
    msgBox.setDefaultButton(sureButton);
    //立即安装
    connect(sureButton,&QPushButton::clicked,this,[&]{
       LocalModelItem *currentItem =   m_nlpLocalModelItemMap.value(modelName);
       if(currentItem)
       {
           currentItem->sldownModel();
       }
    });
    //取消
    connect(cancelButton,&QPushButton::clicked,this,[&]{
        msgBox.setVisible(false);
    });
    msgBox.exec();
}

void LocalModelConfigWidget::showErrorMessage(const QString &message, QWidget *parent)
{
    QMessageBox msgBox(parent);
    msgBox.setIcon(QMessageBox::Question);
    msgBox.setText(message);

    QPushButton *cancelButton = msgBox.addButton(tr("Cancel"), QMessageBox::RejectRole);
    QPushButton *sureButton = msgBox.addButton(tr("Ok"), QMessageBox::AcceptRole);
    msgBox.setDefaultButton(sureButton);
    msgBox.exec();
}

bool LocalModelConfigWidget::showModelInUseMessage(QWidget *parent)
{
    QMessageBox retryMsgBox(parent);
    retryMsgBox.setText(tr("Sorry, the kylin-aiassistant is currently using this model for a task. Please wait for the task to finish before attempting again."));
    retryMsgBox.setIcon(QMessageBox::Critical);

    QPushButton *cancelButton = retryMsgBox.addButton(tr("Cancel"), QMessageBox::RejectRole);
    QPushButton *retryButton = retryMsgBox.addButton(tr("Retry"), QMessageBox::AcceptRole);
    retryMsgBox.setDefaultButton(retryButton);
    retryMsgBox.exec();

    if ((QPushButton *)retryMsgBox.clickedButton() == retryButton) {
        return true;
    }
    return false;
}

bool LocalModelConfigWidget::showConfirmMessage(QWidget *parent)
{

}


bool LocalModelConfigWidget::polkit()
{

}

QMap<QString, LocalModelItem *> &LocalModelConfigWidget::getModelItemMap(AiCapability capability)
{

}

bool LocalModelConfigWidget::checkCurrentLocalModelInstall(const QString &filePath)
{
    //检查当前本地模型是否已经安装
    QFileInfo fileInfo(filePath);
    return  fileInfo.exists();
}

void LocalModelConfigWidget::updateModelMap(PublicLocalModel editModel, AiCapability capability, QString modelName)
{

}
void LocalModelConfigWidget::showCentered()
{
   if (QWidget* mainWindow = QApplication::activeWindow())
   {
       QRect mainGeom = mainWindow->geometry();
       move(mainGeom.x() + (mainGeom.width() - width()) / 2,
       mainGeom.y() + (mainGeom.height() - height()) / 2 + 15);
   }
   adjustPosition(this); // 调用内部调整逻辑
}
