/*
 * Copyright 2025 KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <https://www.gnu.org/licenses/>.
 */

#include "privatemodelconfigwidget.h"
#include "util.h"

PrivateModelConfigWidget::PrivateModelConfigWidget(QWidget *parent) :QDialog(parent)
{
    //初始化布局
    initLayout();
    //初始化私有模型能力
    loadModelConfig();
    //初始化信号槽
    initConnect();
}

void PrivateModelConfigWidget::initLayout()
{
    this->setFixedSize(540, 610);
    this->setWindowTitle(tr("Private Model"));
    m_mainVLayout = new QVBoxLayout();

    initModelTitleLayout();
    initModelLayout();

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

void PrivateModelConfigWidget::initModelTitleLayout() {
    QLabel* backgroundLabel = new QLabel(this);
    backgroundLabel->setFixedHeight(72);
    backgroundLabel->setPixmap(QPixmap(":/res/icon/background.svg"));
    backgroundLabel->setAlignment(Qt::AlignCenter);
    backgroundLabel->setScaledContents(false);
    backgroundLabel->setAccessibleName("kylin-ai-subsystem-modelconfig_QLabel_backgroundLabel");

    // 创建水平布局
    m_titleHLayout = new QHBoxLayout(backgroundLabel);
    m_titleHLayout->setContentsMargins(24, 0, 24, 0);

    // 左侧图标布局
    m_vLeftLayout = new QVBoxLayout();
    m_iconLabel = new QLabel(backgroundLabel);
    m_iconLabel->setAccessibleName("kylin-ai-subsystem-modelconfig_QLabel_m_iconLabel");
    QPixmap iconPixmap(":/res/icon/ukui-private-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_vLeftLayout->addWidget(m_iconLabel);

    // 右侧文本布局
    m_privateHLayout = new QVBoxLayout();
    m_privateHLayout->setContentsMargins(0, 12, 0, 16);

    m_privateLabel = new QLabel(backgroundLabel);
    m_privateLabel->setAccessibleName("kylin-ai-subsystem-modelconfig_QLabel_m_privatLabel");
    m_privateLabel->setMinimumSize(216, 24);
    m_privateLabel->setText(tr("Private Model"));
    QFont privateFont;
    privateFont.setBold(true);
    m_privateLabel->setFont(privateFont);
    m_privateLabel->setStyleSheet("color: #3790FA; background: transparent;");

    m_descripLabel = new kdk::KLabel(backgroundLabel);
    m_descripLabel->setAccessibleName("kylin-ai-subsystem-modelconfig_QLabel_m_descripLabel");
    m_descripLabel->setMinimumSize(450, 20);
    m_descripLabel->setText(tr("Flexible model management to meet personalized usage scenarios"));
    QFont privateDescripFont;
    privateDescripFont.setPointSize(privateFont.pointSize() - 2);
    m_descripLabel->setFont(privateDescripFont);
    setKLabelFontColor(m_descripLabel, "#3790FA");

    m_privateHLayout->addWidget(m_privateLabel);
    m_privateHLayout->addWidget(m_descripLabel);

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

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

void PrivateModelConfigWidget::initModelLayout()
{
    m_baseVLayout = new QVBoxLayout;
    m_baseVLayout->setContentsMargins(0, 30, 0, 0);

    // NLP大语言模型
    m_nlpWidget = new QWidget;
    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);

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

    // NLP描述
    m_nlpDescLabel = new kdk::KLabel(this);
    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->setFixedWidth(400);
    setKLabelFontColor(m_nlpDescLabel, "#808080");

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

    // 添加按钮
    m_nlpAddButton = new kdk::KBorderlessButton;
    m_nlpAddButton->setAccessibleName("kylin-ai-subsystem-modelconfig_kdk::KBorderlessButton_m_nlpAddButton");
    m_nlpAddButton->setFixedSize(60, 28);
    m_nlpAddButton->setIcon(QIcon::fromTheme("list-add-symbolic"));
    m_nlpAddButton->setIconSize(QSize(16, 16));
    m_nlpAddButton->setText(tr("Add"));

    // 已配置模型
    m_nlpPrivateModelGroup = new SettingGroup;
    m_nlpPrivateModelGroup->setAccessibleName("kylin-ai-subsystem-modelconfig_SettingGroup_m_nlpPrivateModelGroup");

    m_nlpHLayout->addLayout(m_nlpDescVLayout);
    m_nlpHLayout->addStretch();
    m_nlpHLayout->addWidget(m_nlpAddButton);

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

    m_nlpWidget->setLayout(m_nlpVLayout);
    // 滚动区域
    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(420);
    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_confirmWidget = new QWidget(this);
    m_confirmWidget->setAccessibleName("kylin-ai-subsystem-modelconfig_QWidget_m_confirmWidget");
    m_confirmPrivateButton = new QPushButton(tr("OK"), this);
    m_confirmPrivateButton->setAccessibleName("kylin-ai-subsystem-modelconfig_QPushButton_m_confirmPrivateButton");
    m_confirmPrivateButton->setProperty("isImportant", true);
    m_confirmPrivateButtoLayout = new QHBoxLayout();
    m_confirmPrivateButtoLayout->setContentsMargins(0, 0, 24, 24);
    m_confirmPrivateButtoLayout->addStretch();
    m_confirmPrivateButtoLayout->addWidget(m_confirmPrivateButton);
    m_confirmWidget->setLayout(m_confirmPrivateButtoLayout);
    m_mainVLayout->addStretch();
    m_mainVLayout->addWidget(m_confirmWidget);
}

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

void PrivateModelConfigWidget::onEditModelItem(AiCapability capability, QString modelName)
{
    if (!polkit()) {
        return;
    }

    KyInfo() << QString("currentEditModelItem:AiCapability=%0, ModelName=%1").arg((qint32)capability).arg(modelName);
    KyInfo() << "currentEditModelItem:modelName"<<modelName;
    if (capability == AiCapability::Nlp) {
        // 随父窗口居中
        PrivateModel currentModel = m_nlpPrivateModelMap[modelName];
        PrivateModelConfigDialog settingDialog(m_nlpPrivateModelMap[modelName], this);
        settingDialog.exec();

    } else if (capability == AiCapability::Vision) {
        // 随父窗口居中
        PrivateModelConfigDialog settingDialog(m_visionPrivateModelMap[modelName], this);
        settingDialog.exec();

    } else if (capability == AiCapability::Speech) {
        // 随父窗口居中
        PrivateModelConfigDialog settingDialog(m_speechPrivateModelMap[modelName], this);
        settingDialog.exec();

    }
}

void PrivateModelConfigWidget::onDeleteModelItem(AiCapability capability, QString modelName)
{
    ModelConfig mc;
    // 删除模型
    if (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 {
        // 未使用，确认弹窗
        bool canProceed = showConfirmMessage(this);
        if (canProceed == true) {
            bool ret = mc.deleteCustomModel(modelName.toStdString());
            if (ret == true) {
                deleteModelItem(capability,  modelName);
                KyInfo() << modelName << " 验证信息clear成功";
            } else {
                showErrorMessage(tr("Failed to delete model"), this);
                KyInfo() << modelName << " 验证信息clear失败, 删除失败";
            }
        }
    }
}

bool PrivateModelConfigWidget::eventFilter(QObject *watched, QEvent *event)
{

    //模型配置
    PrivateModelItemWidget *clickedModelItem = qobject_cast<PrivateModelItemWidget*>(watched);
    if (clickedModelItem) {

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

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

            if (mouseEvent->button() == Qt::LeftButton) { // 判断左键
               // 切换模型
                KyInfo() << "nlpSelectedPrivateModel:" << nlpSelectedPrivateModel;
                clickPrivateModel(clickedModelItem->getAICapability(), clickedModelItem->getModelName());
                return true;
            }
        }
    }
    return QObject::eventFilter(watched, event);

}

void PrivateModelConfigWidget::nlpAddModelItem()
{
    // 设置为随父窗口居中
    PrivateModelConfigDialog settingDialog(this);
    settingDialog.initUIData(AiCapability::Nlp ,DeployType::Custom);
    settingDialog.exec();
}

void PrivateModelConfigWidget::visionAddModelItem()
{

}

void PrivateModelConfigWidget::speechAddModelItem()
{

}


void PrivateModelConfigWidget::loadModelConfig()
{
    // 清空modelmap所有控件
    m_nlpPrivateModelMap.clear();

    // 删除ModelItem对象
    for( PrivateModelItemWidget *item : m_nlpPrivateModelItemMap){
        if(item){
            delete item;
            item = nullptr;
        }
    }
    m_nlpPrivateModelItemMap.clear();


    m_nlpPrivateModelItemList.clear();

    m_nlpPrivateModelGroup->removeAndDeleteAllWidget();

    m_nlpPrivateModelMapUI.clear();


     ModelConfig mc;

     std::string nlpPrivateModel = mc.getCurrentModelName(AiCapability::Nlp,DeployType::Custom);

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

     nlpSelectedPrivateModel = QString::fromStdString(nlpPrivateModel);
     for (auto capability : {AiCapability::Nlp, AiCapability::Vision, AiCapability::Speech}) {

         const auto models = mc.getExtendedModels(capability);
         for (const auto &model : models) {
             //过滤自定义模型
             if(model.deployType == DeployType:: Custom)
             {

                 PrivateModel privateModel;
                 privateModel.capability = model.capability;
                 privateModel.vendor = QString::fromStdString(model.vendor);
                 privateModel.modelName = QString::fromStdString(model.modelName);
                 privateModel.modelVersion = QString::fromStdString(model.modelVersion);
                 privateModel.apiUrl = QString::fromStdString(model.apiUrl);
                 privateModel.multiAuths  = mc.getModelAuthentications(model.modelName);

                 for (const auto &authen : privateModel.multiAuths) {
                     KyInfo() << "loadModelConfig配置项名称" << QString::fromStdString( authen.itemName);
                     for (const auto &au : authen.authentications) {
                         if (au.key == "apiKey") {
                             privateModel.apiKey = QString::fromStdString(au.value);
                         }
                     }
                 }

                 switch (capability) {
                 case AiCapability::Nlp:
                     loadModelItem(privateModel, nlpSelectedPrivateModel);
                     break;
                 case AiCapability::Vision:
                     loadModelItem(privateModel, visionSelectedPrivateModel);
                     break;
                 case AiCapability::Speech:
                     loadModelItem(privateModel, speechSelectedPrivateModel);
                     break;
                 default:
                     break;
                 }
             }

         }
     }

}

void PrivateModelConfigWidget::initConnect()
{
    connect(m_nlpAddButton, &QPushButton::clicked, this, [this](){
        this->nlpAddModelItem();
    });
    connect(m_confirmPrivateButton, &QPushButton::clicked, this, [this](){
        this->close();
    });
}

void PrivateModelConfigWidget::addModelItem(PrivateModel model)
{
    UkccFrame *itemFrame = new UkccFrame(this);
    itemFrame->setMinimumWidth(496);
    itemFrame->setMaximumWidth(496);
    itemFrame->setFixedHeight(56);
    itemFrame->setObjectName(model.modelName);
    QHBoxLayout *layItem = new QHBoxLayout(itemFrame);
    layItem->setContentsMargins(0, 0, 0, 0);

    PrivateModelItemWidget *item = new PrivateModelItemWidget(model.capability, model.modelName, itemFrame);
    item->installEventFilter(this);
    connect(item, &PrivateModelItemWidget::sigEdit, this, &PrivateModelConfigWidget::onEditModelItem);
    connect(item, &PrivateModelItemWidget::sigDelete, this,&PrivateModelConfigWidget::onDeleteModelItem);

    layItem->addWidget(item);
    if (model.capability == AiCapability::Nlp)
    {
        m_nlpPrivateModelItemList.append(item);
        m_nlpPrivateModelMap[model.modelName] = model;
        m_nlpPrivateModelItemMap[model.modelName] = item;
        m_nlpPrivateModelMapUI[model.modelName] = itemFrame;
        m_nlpPrivateModelGroup->addWidget(itemFrame);

        // 第一个添加的模型，设置为选中
        if (m_nlpPrivateModelItemMap.count() == 1) {
            item->showSelectedIcon(true);
            nlpSelectedPrivateModel = model.modelName;
        }
    }
    else if (model.capability == AiCapability::Vision)
    {
        m_visionPrivateModelItemList.append(item);
        m_visionPrivateModelMap[model.modelName] = model;
        m_visionPrivateModelItemMap[model.modelName] = item;
        m_visionPrivateModelMapUI[model.modelName] = itemFrame;
        m_visionPrivateModelGroup->addWidget(itemFrame);

        // 第一个添加的模型，设置为选中
        if (m_visionPrivateModelItemMap.count() == 1) {
            item->showSelectedIcon(true);
            visionSelectedPrivateModel = model.modelName;
        }
    }
    else if (model.capability == AiCapability::Speech)
    {
        m_speechPrivateModelItemList.append(item);
        m_speechPrivateModelMap[model.modelName] = model;
        m_speechPrivateModelItemMap[model.modelName] = item;
        m_speechPrivateModelMapUI[model.modelName] = itemFrame;
        m_speechPrivateModelGroup->addWidget(itemFrame);

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

}

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

    KyInfo() << "loadModelConfig模型名称" <<  model.modelName;
    for (const auto &authen : multiAuths) {
        KyInfo() << "loadModelConfig配置项名称" << QString::fromStdString(authen.itemName);
        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 << "验证信息为空，当前自定义模型无需限制key的输入，正常加载";
        }
    }

    UkccFrame *itemFrame = new UkccFrame(this);
    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);

    PrivateModelItemWidget *item = new PrivateModelItemWidget(model.capability, model.modelName, itemFrame);
    item->setAccessibleName("kylin-ai-subsystem-modelconfig_PrivateModelItemWidget_item");
    item->installEventFilter(this);
    connect(item, &PrivateModelItemWidget::sigEdit, this, &PrivateModelConfigWidget::onEditModelItem);
    connect(item, &PrivateModelItemWidget::sigDelete, this, &PrivateModelConfigWidget::onDeleteModelItem);

    layItem->addWidget(item);

    if (model.capability == AiCapability::Nlp)
    {
        m_nlpPrivateModelItemList.append(item);
        m_nlpPrivateModelMap[model.modelName] = model;
        m_nlpPrivateModelItemMap[model.modelName] = item;
        m_nlpPrivateModelMapUI[model.modelName] = itemFrame;
        m_nlpPrivateModelGroup->addWidget(itemFrame);

        // 设置为选中
        if (model.modelName == curSelectedName) {
            item->showSelectedIcon(true);
            nlpSelectedPrivateModel = model.modelName;
        }
    }
    else if (model.capability == AiCapability::Vision)
    {
        m_visionPrivateModelItemList.append(item);
        m_visionPrivateModelMap[model.modelName] = model;
        m_visionPrivateModelItemMap[model.modelName] = item;
        m_visionPrivateModelMapUI[model.modelName] = itemFrame;
        m_visionPrivateModelGroup->addWidget(itemFrame);

        // 设置为选中
        if (model.modelName == curSelectedName) {
            item->showSelectedIcon(true);
            visionSelectedPrivateModel = model.modelName;
        }
    }
    else if (model.capability == AiCapability::Speech)
    {
        m_speechPrivateModelItemList.append(item);
        m_speechPrivateModelMap[model.modelName] = model;
        m_speechPrivateModelItemMap[model.modelName] = item;
        m_speechPrivateModelMapUI[model.modelName] = itemFrame;
        m_speechPrivateModelGroup->addWidget(itemFrame);

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

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

    if (capability == AiCapability::Nlp)
    {
        // 手动删除 ModelItem 对象
        auto item = m_nlpPrivateModelItemList.takeAt(m_nlpPrivateModelItemList.indexOf(m_nlpPrivateModelItemMap[modelName]));
        if (m_nlpPrivateModelItemMap.contains(modelName)) {
            if (m_nlpPrivateModelItemMap[modelName]) {
                delete m_nlpPrivateModelItemMap[modelName];
                m_nlpPrivateModelItemMap[modelName] = nullptr;
            }
        }
        m_nlpPrivateModelMap.remove(modelName);
        m_nlpPrivateModelItemMap.remove(modelName);
        m_nlpPrivateModelGroup->removeWidget(m_nlpPrivateModelMapUI[modelName]);
        m_nlpPrivateModelMapUI.remove(modelName);

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

                KyInfo() << "============删除后 nlp firstModelName" << firstModelName;

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

            } else {
                // 删除后无模型
                KyInfo() << " nlpModelItemMap为空";
                nlpSelectedPrivateModel = "";
            }
        }
    }
    else if (capability == AiCapability::Vision)
    {
        // 手动删除 ModelItem 对象
        auto item = m_visionPrivateModelItemList.takeAt(m_visionPrivateModelItemList.indexOf(m_visionPrivateModelItemMap[modelName]));
        if (m_visionPrivateModelItemMap.contains(modelName)) {
            if (m_visionPrivateModelItemMap[modelName]) {
                delete m_visionPrivateModelItemMap[modelName];
                m_visionPrivateModelItemMap[modelName] = nullptr;
            }
        }
        m_visionPrivateModelMap.remove(modelName);
        m_visionPrivateModelItemMap.remove(modelName);
        m_visionPrivateModelGroup->removeWidget(m_visionPrivateModelMapUI[modelName]);
        m_visionPrivateModelMapUI.remove(modelName);

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

                KyInfo() << "============删除后 vision firstModelName" << firstModelName;

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

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

    }
    else if (capability == AiCapability::Speech)
    {
        // 手动删除 ModelItem 对象
        auto item = m_speechPrivateModelItemList.takeAt(m_speechPrivateModelItemList.indexOf(m_speechPrivateModelItemMap[modelName]));
        if (m_speechPrivateModelItemMap.contains(modelName)) {
            if (m_speechPrivateModelItemMap[modelName]) {
                delete m_speechPrivateModelItemMap[modelName];
                m_speechPrivateModelItemMap[modelName] = nullptr;
            }
        }
        m_speechPrivateModelMap.remove(modelName);
        m_speechPrivateModelItemMap.remove(modelName);
        m_speechPrivateModelGroup->removeWidget(m_speechPrivateModelMapUI[modelName]);
        m_speechPrivateModelMapUI.remove(modelName);

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

                // 删除后，设置剩下模型中的第一个为选中
                PrivateModelItemWidget* firstItem = m_speechPrivateModelItemList.first();
                QString firstModelName = firstItem->getModelName();

                KyInfo() << "============删除后 speech firstModelName" << firstModelName;

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

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



}

void PrivateModelConfigWidget::switchModelItem(AiCapability capability, QString modelName)
{
    QMap<QString, PrivateModelItemWidget*> *modelItemMap = nullptr;

    if (capability == AiCapability::Nlp) {
        modelItemMap = &m_nlpPrivateModelItemMap;

    } else if (capability == AiCapability::Vision) {
        modelItemMap = &m_visionPrivateModelItemMap;

    } else if (capability == AiCapability::Speech) {
        modelItemMap = &m_speechPrivateModelItemMap;
    }

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

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

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

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

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

bool PrivateModelConfigWidget::setSelectPrivateModelConfig(PrivateModel model)
{
    ModelConfig mc;
    bool ret1 = mc.addCustomModel(model.modelName.toStdString(), model.modelVersion.toStdString(),
                                  model.apiKey.toStdString(), model.apiUrl.toStdString());
    if (ret1 == true)
    {
        bool ret2 = setSelectPrivateModelName(model.capability, DeployType::Custom, model.modelName);
        if (ret2 == false)
        {
            KyInfo() << "setCurrentModelName failed:" << ret2;
            return false;
        }
    } else {
        KyInfo() << "addCustomModel failed:" << ret1;
        return false;
    }
    return true;
}

bool PrivateModelConfigWidget::setSelectPrivateModelName(AiCapability capability, DeployType deployType, QString modelName)
{
    KyInfo() << "setSelectPrivateModelName" << modelName;
    ModelConfig mc;
    bool ret2 = mc.setCurrentModelName(capability, deployType, modelName.toStdString());

    if ( ret2 == true)
    {
        KyInfo() << "setCurrentModelName success:"<< ret2;
    } else {
        KyInfo() << "setCurrentModelName failed:"<< ret2;
    }
    return ret2;
}

bool PrivateModelConfigWidget::editSelectPrivateModel(PrivateModel model, bool isContinuousSelected,
                                                      bool isRealTimeSelected, bool isValueChanged, QDialog *parentDialog) {
    bool isSwitchStateChanged = false;

    if (model.capability == AiCapability::Speech) {
        if (continuousSelected != isContinuousSelected) {
            isSwitchStateChanged = true;
        }
        if (realtimeSelected != isRealTimeSelected) {
            isSwitchStateChanged = true;
        }
    }

    while (getModelStatus(model.modelName) == ModelStatus::Running) {
        // NLP or VISION or SPEECH 正在使用，重试弹窗
        KyInfo() << "正在使用" << static_cast<int>(model.capability);

        if (isValueChanged == false && isSwitchStateChanged == false) {
            KyInfo() << "检查无修改内容，仅查看，关闭弹窗";
            return true;
        }

        bool canProceed = showModelInUseMessage(parentDialog);
        if (canProceed == true) {
            continue;
        } else {
            KyInfo() << "取消本次操作";
            return false;
        }
    }

    // 未使用
    // 当前选中的，无需再setCurrentModelName
    // 更新当前模型信息
    bool ret =  this->updatePrivateModel(model);
    if (ret == true) {
        // 发送信号告知已设置模型，重新创建会话
        if (model.capability == AiCapability::Nlp) {
            m_nlpPrivateModelMap[model.modelName] = model;

        } else if (model.capability== AiCapability::Vision) {
            m_visionPrivateModelMap[model.modelName] = model;

        } else if (model.capability== AiCapability::Speech) {
            m_speechPrivateModelMap[model.modelName] = model;
        }

        if (model.capability == AiCapability::Speech) {
            // 同步两个开关的状态
            continuousSelected = isContinuousSelected;
            realtimeSelected = isRealTimeSelected;
        }

    } else {
        showErrorMessage(tr("Model Editing failed"), parentDialog);
        KyInfo() << "编辑模型" << model.modelName << "失败";
        return false;
    }
    return true;
}

void PrivateModelConfigWidget::clickPrivateModel(AiCapability capability, QString modelName)
{
    KyInfo() << "正要切换到" << static_cast<int>(capability) << modelName ;
    KyInfo() << "当前正在回答的选中模型为" << nlpSelectedPrivateModel;

    bool ret = checkModelSelection(capability, modelName);

    if(ret == true){
        return;
    }
    else {
        if ((capability == AiCapability::Nlp &&  (getModelStatus(nlpSelectedPrivateModel) == ModelStatus::Running))
                || (capability == AiCapability::Vision &&  (getModelStatus(visionSelectedPrivateModel) == ModelStatus::Running))
                || (capability == AiCapability::Speech &&  (getModelStatus(speechSelectedPrivateModel) == ModelStatus::Running))) {
            // NLP or VISION or SPEECH 正在使用
            KyInfo() << "正在使用" << static_cast<int>(capability);
            bool canProceed = showModelInUseMessage(this);
            if (canProceed == true) {
                clickPrivateModel(capability, modelName);
            } else {
                 KyInfo() << "取消本次操作";
                return;
            }
        } else {
            bool ret = setSelectPrivateModelName(capability, DeployType::Custom, modelName);
            if (ret == true) {
                switchModelItem(capability, modelName);
                KyInfo() << modelName << " 设置为选中模型成功";
            } else {
                showErrorMessage(tr("Model switching failed"),this);
                KyInfo() << modelName << " 设置为选中模型失败";
            }
        }
    }
}

bool PrivateModelConfigWidget::clearModelMultiAuths(AiCapability capability, QString modelName)
{
    ModelConfig mc;
    bool ret = mc.clearModelAuthentications(modelName.toStdString());

    return ret;
}

bool PrivateModelConfigWidget::clearCustomModel(AiCapability capability, QString modelName)
{
    ModelConfig mc;
    bool ret = mc.deleteCustomModel(modelName.toStdString());

    return ret;
}

bool PrivateModelConfigWidget::addPrivateModel(PrivateModel model)
{
    ModelConfig mc;
    bool ret = mc.addCustomModel(model.modelName.toStdString(), model.modelVersion.toStdString(),
                                  model.apiKey.toStdString(), model.apiUrl.toStdString());
    if (ret == true)
    {
        return true;
    } else {
        KyInfo() << "addPrivateModel failed:" << ret;
        return false;
    }

}

bool PrivateModelConfigWidget::updatePrivateModel(PrivateModel model)
{
    ModelConfig mc;
    bool ret1 = mc.setCustomModelApiUrl(model.modelName.toStdString(), model.apiUrl.toStdString());
    bool ret2 = mc.setCustomModelVersion(model.modelName.toStdString(), model.modelVersion.toStdString());
    bool ret3 = mc.setModelAuthentications(model.modelName.toStdString(), model.multiAuths);
    if (ret1 == true && ret2 == true && ret3 == true)
    {
        return true;
    } else {
        KyInfo() << "updateCustomModel failed"<<"ret1"<<ret1<<"ret2"<<ret2<<"ret3"<<ret3;
        return false;
    }

}

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

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

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

bool PrivateModelConfigWidget::polkit()
{
    PolkitQt1::Authority::Result result;
    result = PolkitQt1::Authority::instance()->checkAuthorizationSync(
                "org.kylin-ai-subsystem-modelconfig.policy",
                PolkitQt1::UnixProcessSubject(QCoreApplication::applicationPid()),
                PolkitQt1::Authority::AllowUserInteraction);
    KyInfo() << "PolkitQt1 Authority result:" << result;
    if (result == PolkitQt1::Authority::Yes) { //认证通过
        KyInfo() << QString("operation authorized");
        return true;
    } else {
        KyInfo() << QString("not authorized");
        return false;
    }

}

QMap<QString, PrivateModelItemWidget *> &PrivateModelConfigWidget::getModelItemMap(AiCapability capability)
{
    if (capability == AiCapability::Nlp) {
        return m_nlpPrivateModelItemMap;
    } else if (capability == AiCapability::Vision) {
        return m_visionPrivateModelItemMap;
    } else if (capability == AiCapability::Speech) {
        return m_speechPrivateModelItemMap;
}
}
void PrivateModelConfigWidget::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); // 调用内部调整逻辑
}
