#include "ModelSettingsDialog.h"
#include <QDir>
#include <QFileInfo>
#include <QStandardPaths>
#include <QDebug>

ModelSettingsDialog::ModelSettingsDialog(QWidget* parent) 
    : QDialog(parent), settings(new QSettings(this)) {
    setWindowTitle("模型设置");
    setModal(true);
    resize(800, 600);
    
    setupUI();
    connectSignals();
    loadSettings();
}

ModelSettingsDialog::~ModelSettingsDialog() {
}

void ModelSettingsDialog::setupUI() {
    auto* mainLayout = new QVBoxLayout(this);
    
    // 创建标签页控件
    tabWidget = new QTabWidget(this);
    
    setupOfflineASRTab();
    setupOnlineASRTab();
    setupKWSTab();
    setupTTSTab();
    setupAdvancedTab();
    
    mainLayout->addWidget(tabWidget);
    
    // 按钮区域
    auto* buttonLayout = new QHBoxLayout();
    
    scanBtn = new QPushButton("扫描模型", this);
    scanBtn->setToolTip("自动扫描系统中的可用模型");
    
    resetBtn = new QPushButton("重置默认", this);
    resetBtn->setToolTip("重置为默认配置");
    
    buttonLayout->addWidget(scanBtn);
    buttonLayout->addWidget(resetBtn);
    buttonLayout->addStretch();
    
    saveBtn = new QPushButton("保存", this);
    saveBtn->setDefault(true);
    cancelBtn = new QPushButton("取消", this);
    
    buttonLayout->addWidget(saveBtn);
    buttonLayout->addWidget(cancelBtn);
    
    mainLayout->addLayout(buttonLayout);
}

void ModelSettingsDialog::setupOfflineASRTab() {
    offlineAsrTab = new QWidget();
    tabWidget->addTab(offlineAsrTab, "离线语音识别");
    
    auto* layout = new QVBoxLayout(offlineAsrTab);
    
    // 模型选择组
    auto* modelGroup = new QGroupBox("模型选择", this);
    auto* modelLayout = new QGridLayout(modelGroup);
    
    modelLayout->addWidget(new QLabel("预设模型:"), 0, 0);
    offlineAsrModelCombo = new QComboBox(this);
    offlineAsrModelCombo->addItem("自定义", "custom");
    offlineAsrModelCombo->addItem("Paraformer中文模型", "paraformer-zh");
    offlineAsrModelCombo->addItem("Whisper多语言模型", "whisper-multilingual");
    modelLayout->addWidget(offlineAsrModelCombo, 0, 1, 1, 2);
    
    layout->addWidget(modelGroup);
    
    // 模型路径组
    auto* pathGroup = new QGroupBox("模型路径", this);
    auto* pathLayout = new QGridLayout(pathGroup);
    
    pathLayout->addWidget(new QLabel("模型文件:"), 0, 0);
    offlineAsrModelPathEdit = new QLineEdit(this);
    offlineAsrModelPathEdit->setPlaceholderText("选择.onnx模型文件...");
    auto* browseModelBtn = new QPushButton("浏览", this);
    pathLayout->addWidget(offlineAsrModelPathEdit, 0, 1);
    pathLayout->addWidget(browseModelBtn, 0, 2);
    
    pathLayout->addWidget(new QLabel("词汇表文件:"), 1, 0);
    offlineAsrTokensPathEdit = new QLineEdit(this);
    offlineAsrTokensPathEdit->setPlaceholderText("选择tokens.txt文件...");
    auto* browseTokensBtn = new QPushButton("浏览", this);
    pathLayout->addWidget(offlineAsrTokensPathEdit, 1, 1);
    pathLayout->addWidget(browseTokensBtn, 1, 2);
    
    layout->addWidget(pathGroup);
    
    // 模型信息组
    auto* infoGroup = new QGroupBox("模型信息", this);
    auto* infoLayout = new QVBoxLayout(infoGroup);
    
    offlineAsrModelInfoEdit = new QTextEdit(this);
    offlineAsrModelInfoEdit->setMaximumHeight(100);
    offlineAsrModelInfoEdit->setPlaceholderText("模型信息将显示在这里...");
    infoLayout->addWidget(offlineAsrModelInfoEdit);
    
    auto* testLayout = new QHBoxLayout();
    testOfflineASRBtn = new QPushButton("测试模型", this);
    testOfflineASRBtn->setEnabled(false);
    testLayout->addStretch();
    testLayout->addWidget(testOfflineASRBtn);
    
    infoLayout->addLayout(testLayout);
    layout->addWidget(infoGroup);
    
    layout->addStretch();
    
    // 连接信号
    connect(browseModelBtn, &QPushButton::clicked, this, &ModelSettingsDialog::browseOfflineASRModel);
    connect(browseTokensBtn, &QPushButton::clicked, this, &ModelSettingsDialog::browseOfflineASRTokens);
}

void ModelSettingsDialog::setupOnlineASRTab() {
    onlineAsrTab = new QWidget();
    tabWidget->addTab(onlineAsrTab, "在线语音识别");
    
    auto* layout = new QVBoxLayout(onlineAsrTab);
    
    // 模型选择组
    auto* modelGroup = new QGroupBox("模型选择", this);
    auto* modelLayout = new QGridLayout(modelGroup);
    
    modelLayout->addWidget(new QLabel("预设模型:"), 0, 0);
    onlineAsrModelCombo = new QComboBox(this);
    onlineAsrModelCombo->addItem("自定义", "custom");
    onlineAsrModelCombo->addItem("Streaming Paraformer中英文模型", "streaming-paraformer-zh-en");
    onlineAsrModelCombo->addItem("Streaming Zipformer中英文模型", "streaming-zipformer-zh-en");
    modelLayout->addWidget(onlineAsrModelCombo, 0, 1, 1, 2);
    
    layout->addWidget(modelGroup);
    
    // 模型路径组
    auto* pathGroup = new QGroupBox("模型路径", this);
    auto* pathLayout = new QGridLayout(pathGroup);
    
    pathLayout->addWidget(new QLabel("编码器文件:"), 0, 0);
    onlineAsrModelPathEdit = new QLineEdit(this);
    onlineAsrModelPathEdit->setPlaceholderText("选择encoder.onnx文件...");
    auto* browseModelBtn = new QPushButton("浏览", this);
    pathLayout->addWidget(onlineAsrModelPathEdit, 0, 1);
    pathLayout->addWidget(browseModelBtn, 0, 2);
    
    pathLayout->addWidget(new QLabel("词汇表文件:"), 1, 0);
    onlineAsrTokensPathEdit = new QLineEdit(this);
    onlineAsrTokensPathEdit->setPlaceholderText("选择tokens.txt文件...");
    auto* browseTokensBtn = new QPushButton("浏览", this);
    pathLayout->addWidget(onlineAsrTokensPathEdit, 1, 1);
    pathLayout->addWidget(browseTokensBtn, 1, 2);
    
    layout->addWidget(pathGroup);
    
    // 模型信息组
    auto* infoGroup = new QGroupBox("模型信息", this);
    auto* infoLayout = new QVBoxLayout(infoGroup);
    
    onlineAsrModelInfoEdit = new QTextEdit(this);
    onlineAsrModelInfoEdit->setMaximumHeight(100);
    onlineAsrModelInfoEdit->setPlaceholderText("模型信息将显示在这里...");
    infoLayout->addWidget(onlineAsrModelInfoEdit);
    
    auto* testLayout = new QHBoxLayout();
    testOnlineASRBtn = new QPushButton("测试模型", this);
    testOnlineASRBtn->setEnabled(false);
    testLayout->addStretch();
    testLayout->addWidget(testOnlineASRBtn);
    
    infoLayout->addLayout(testLayout);
    layout->addWidget(infoGroup);
    
    layout->addStretch();
    
    // 连接信号
    connect(browseModelBtn, &QPushButton::clicked, this, &ModelSettingsDialog::browseOnlineASRModel);
    connect(browseTokensBtn, &QPushButton::clicked, this, &ModelSettingsDialog::browseOnlineASRTokens);
}

void ModelSettingsDialog::setupKWSTab() {
    kwsTab = new QWidget();
    tabWidget->addTab(kwsTab, "语音唤醒 (KWS)");
    
    auto* layout = new QVBoxLayout(kwsTab);
    
    // 模型选择组
    auto* modelGroup = new QGroupBox("模型选择", this);
    auto* modelLayout = new QGridLayout(modelGroup);
    
    modelLayout->addWidget(new QLabel("预设模型:"), 0, 0);
    kwsModelCombo = new QComboBox(this);
    kwsModelCombo->addItem("自定义", "custom");
    kwsModelCombo->addItem("Zipformer Wenetspeech 3.3M", "zipformer-wenetspeech-3.3m");
    kwsModelCombo->addItem("Zipformer Gigaspeech", "zipformer-gigaspeech");
    modelLayout->addWidget(kwsModelCombo, 0, 1, 1, 2);
    
    layout->addWidget(modelGroup);
    
    // 模型路径组
    auto* pathGroup = new QGroupBox("模型路径", this);
    auto* pathLayout = new QGridLayout(pathGroup);
    
    pathLayout->addWidget(new QLabel("模型文件:"), 0, 0);
    kwsModelPathEdit = new QLineEdit(this);
    kwsModelPathEdit->setPlaceholderText("选择.onnx模型文件...");
    auto* browseModelBtn = new QPushButton("浏览", this);
    pathLayout->addWidget(kwsModelPathEdit, 0, 1);
    pathLayout->addWidget(browseModelBtn, 0, 2);
    
    pathLayout->addWidget(new QLabel("词汇表文件:"), 1, 0);
    kwsTokensPathEdit = new QLineEdit(this);
    kwsTokensPathEdit->setPlaceholderText("选择tokens.txt文件...");
    auto* browseTokensBtn = new QPushButton("浏览", this);
    pathLayout->addWidget(kwsTokensPathEdit, 1, 1);
    pathLayout->addWidget(browseTokensBtn, 1, 2);
    
    pathLayout->addWidget(new QLabel("关键词文件:"), 2, 0);
    kwsKeywordsPathEdit = new QLineEdit(this);
    kwsKeywordsPathEdit->setPlaceholderText("选择keywords.txt文件...");
    auto* browseKeywordsBtn = new QPushButton("浏览", this);
    pathLayout->addWidget(kwsKeywordsPathEdit, 2, 1);
    pathLayout->addWidget(browseKeywordsBtn, 2, 2);
    
    layout->addWidget(pathGroup);
    
    // 模型信息组
    auto* infoGroup = new QGroupBox("模型信息", this);
    auto* infoLayout = new QVBoxLayout(infoGroup);
    
    kwsModelInfoEdit = new QTextEdit(this);
    kwsModelInfoEdit->setMaximumHeight(100);
    kwsModelInfoEdit->setPlaceholderText("模型信息将显示在这里...");
    infoLayout->addWidget(kwsModelInfoEdit);
    
    auto* testLayout = new QHBoxLayout();
    testKWSBtn = new QPushButton("测试模型", this);
    testKWSBtn->setEnabled(false);
    testLayout->addStretch();
    testLayout->addWidget(testKWSBtn);
    
    infoLayout->addLayout(testLayout);
    layout->addWidget(infoGroup);
    
    // KWS参数设置组
    kwsParamsGroup = new QGroupBox("识别参数设置", this);
    auto* paramsLayout = new QGridLayout(kwsParamsGroup);
    
    // 关键词阈值
    paramsLayout->addWidget(new QLabel("关键词阈值:"), 0, 0);
    kwsThresholdEdit = new QLineEdit(this);
    kwsThresholdEdit->setText("0.25");
    kwsThresholdEdit->setToolTip("范围: 0.01-1.0，越低越容易检测，建议: 0.25");
    paramsLayout->addWidget(kwsThresholdEdit, 0, 1);
    paramsLayout->addWidget(new QLabel("(0.01-1.0, 推荐0.25)"), 0, 2);
    
    // 最大活跃路径数
    paramsLayout->addWidget(new QLabel("最大活跃路径:"), 1, 0);
    kwsMaxActivePathsEdit = new QLineEdit(this);
    kwsMaxActivePathsEdit->setText("8");
    kwsMaxActivePathsEdit->setToolTip("范围: 1-16，越大识别率越高但速度越慢，建议: 8");
    paramsLayout->addWidget(kwsMaxActivePathsEdit, 1, 1);
    paramsLayout->addWidget(new QLabel("(1-16, 推荐8)"), 1, 2);
    
    // 尾随空白数
    paramsLayout->addWidget(new QLabel("尾随空白数:"), 2, 0);
    kwsTrailingBlanksEdit = new QLineEdit(this);
    kwsTrailingBlanksEdit->setText("2");
    kwsTrailingBlanksEdit->setToolTip("范围: 1-5，越大端点检测越宽松，建议: 2");
    paramsLayout->addWidget(kwsTrailingBlanksEdit, 2, 1);
    paramsLayout->addWidget(new QLabel("(1-5, 推荐2)"), 2, 2);
    
    // 关键词分数权重
    paramsLayout->addWidget(new QLabel("关键词分数权重:"), 3, 0);
    kwsKeywordsScoreEdit = new QLineEdit(this);
    kwsKeywordsScoreEdit->setText("1.5");
    kwsKeywordsScoreEdit->setToolTip("范围: 0.5-3.0，越大关键词权重越高，建议: 1.5");
    paramsLayout->addWidget(kwsKeywordsScoreEdit, 3, 1);
    paramsLayout->addWidget(new QLabel("(0.5-3.0, 推荐1.5)"), 3, 2);
    
    // 线程数
    paramsLayout->addWidget(new QLabel("处理线程数:"), 4, 0);
    kwsNumThreadsEdit = new QLineEdit(this);
    kwsNumThreadsEdit->setText("2");
    kwsNumThreadsEdit->setToolTip("范围: 1-4，越大速度越快但占用资源越多，建议: 2");
    paramsLayout->addWidget(kwsNumThreadsEdit, 4, 1);
    paramsLayout->addWidget(new QLabel("(1-4, 推荐2)"), 4, 2);
    
    // 重置按钮
    kwsResetParamsBtn = new QPushButton("恢复默认参数", this);
    kwsResetParamsBtn->setToolTip("将所有参数恢复为推荐的默认值");
    paramsLayout->addWidget(kwsResetParamsBtn, 5, 0, 1, 3);
    
    // 参数说明
    auto* paramsHelpLabel = new QLabel(
        "💡 参数调整建议：\n"
        "• 识别率低：降低阈值(0.15-0.25)，增加活跃路径(8-12)\n"
        "• 误识别多：提高阈值(0.3-0.5)，减少活跃路径(4-6)\n"
        "• 响应慢：增加线程数(2-4)，减少尾随空白(1)\n"
        "• 修改参数后需要重启KWS检测才能生效", this);
    paramsHelpLabel->setWordWrap(true);
    paramsHelpLabel->setStyleSheet("QLabel { color: #666; font-size: 11px; padding: 10px; background-color: #f5f5f5; border-radius: 5px; }");
    paramsLayout->addWidget(paramsHelpLabel, 6, 0, 1, 3);
    
    layout->addWidget(kwsParamsGroup);
    
    layout->addStretch();
    
    // 连接信号
    connect(browseModelBtn, &QPushButton::clicked, this, &ModelSettingsDialog::browseKWSModel);
    connect(browseTokensBtn, &QPushButton::clicked, this, &ModelSettingsDialog::browseKWSTokens);
    connect(browseKeywordsBtn, &QPushButton::clicked, this, &ModelSettingsDialog::browseKWSKeywords);
    connect(kwsResetParamsBtn, &QPushButton::clicked, this, &ModelSettingsDialog::resetKWSParams);
    
    // 连接参数变化信号
    connect(kwsThresholdEdit, &QLineEdit::textChanged, this, &ModelSettingsDialog::onKWSParamsChanged);
    connect(kwsMaxActivePathsEdit, &QLineEdit::textChanged, this, &ModelSettingsDialog::onKWSParamsChanged);
    connect(kwsTrailingBlanksEdit, &QLineEdit::textChanged, this, &ModelSettingsDialog::onKWSParamsChanged);
    connect(kwsKeywordsScoreEdit, &QLineEdit::textChanged, this, &ModelSettingsDialog::onKWSParamsChanged);
    connect(kwsNumThreadsEdit, &QLineEdit::textChanged, this, &ModelSettingsDialog::onKWSParamsChanged);
}

void ModelSettingsDialog::setupTTSTab() {
    ttsTab = new QWidget();
    tabWidget->addTab(ttsTab, "语音合成 (TTS)");
    
    auto* layout = new QVBoxLayout(ttsTab);
    
    // 模型选择组
    auto* modelGroup = new QGroupBox("模型选择", this);
    auto* modelLayout = new QGridLayout(modelGroup);
    
    modelLayout->addWidget(new QLabel("预设模型:"), 0, 0);
    ttsModelCombo = new QComboBox(this);
    ttsModelCombo->addItem("自定义", "custom");
    ttsModelCombo->addItem("MeloTTS中英文混合", "melo-zh-en");
    ttsModelCombo->addItem("VITS中文模型", "vits-zh");
    modelLayout->addWidget(ttsModelCombo, 0, 1, 1, 2);
    
    layout->addWidget(modelGroup);
    
    // 模型路径组
    auto* pathGroup = new QGroupBox("模型路径", this);
    auto* pathLayout = new QGridLayout(pathGroup);
    
    pathLayout->addWidget(new QLabel("模型文件:"), 0, 0);
    ttsModelPathEdit = new QLineEdit(this);
    ttsModelPathEdit->setPlaceholderText("选择.onnx模型文件...");
    auto* browseModelBtn = new QPushButton("浏览", this);
    pathLayout->addWidget(ttsModelPathEdit, 0, 1);
    pathLayout->addWidget(browseModelBtn, 0, 2);
    
    pathLayout->addWidget(new QLabel("词汇表文件:"), 1, 0);
    ttsTokensPathEdit = new QLineEdit(this);
    ttsTokensPathEdit->setPlaceholderText("选择tokens.txt文件...");
    auto* browseTokensBtn = new QPushButton("浏览", this);
    pathLayout->addWidget(ttsTokensPathEdit, 1, 1);
    pathLayout->addWidget(browseTokensBtn, 1, 2);
    
    pathLayout->addWidget(new QLabel("词典文件:"), 2, 0);
    ttsLexiconPathEdit = new QLineEdit(this);
    ttsLexiconPathEdit->setPlaceholderText("选择lexicon.txt文件...");
    auto* browseLexiconBtn = new QPushButton("浏览", this);
    pathLayout->addWidget(ttsLexiconPathEdit, 2, 1);
    pathLayout->addWidget(browseLexiconBtn, 2, 2);
    
    pathLayout->addWidget(new QLabel("字典目录:"), 3, 0);
    ttsDictDirPathEdit = new QLineEdit(this);
    ttsDictDirPathEdit->setPlaceholderText("选择dict目录...");
    auto* browseDictBtn = new QPushButton("浏览", this);
    pathLayout->addWidget(ttsDictDirPathEdit, 3, 1);
    pathLayout->addWidget(browseDictBtn, 3, 2);
    
    pathLayout->addWidget(new QLabel("数据目录:"), 4, 0);
    ttsDataDirPathEdit = new QLineEdit(this);
    ttsDataDirPathEdit->setPlaceholderText("选择espeak-ng-data目录...");
    auto* browseDataBtn = new QPushButton("浏览", this);
    pathLayout->addWidget(ttsDataDirPathEdit, 4, 1);
    pathLayout->addWidget(browseDataBtn, 4, 2);
    
    layout->addWidget(pathGroup);
    
    // 模型信息组
    auto* infoGroup = new QGroupBox("模型信息", this);
    auto* infoLayout = new QVBoxLayout(infoGroup);
    
    ttsModelInfoEdit = new QTextEdit(this);
    ttsModelInfoEdit->setMaximumHeight(100);
    ttsModelInfoEdit->setPlaceholderText("模型信息将显示在这里...");
    infoLayout->addWidget(ttsModelInfoEdit);
    
    auto* testLayout = new QHBoxLayout();
    testTTSBtn = new QPushButton("测试模型", this);
    testTTSBtn->setEnabled(false);
    testLayout->addStretch();
    testLayout->addWidget(testTTSBtn);
    
    infoLayout->addLayout(testLayout);
    layout->addWidget(infoGroup);
    
    layout->addStretch();
    
    // 连接信号
    connect(browseModelBtn, &QPushButton::clicked, this, &ModelSettingsDialog::browseTTSModel);
    connect(browseTokensBtn, &QPushButton::clicked, this, &ModelSettingsDialog::browseTTSTokens);
    connect(browseLexiconBtn, &QPushButton::clicked, this, &ModelSettingsDialog::browseTTSLexicon);
    connect(browseDictBtn, &QPushButton::clicked, this, &ModelSettingsDialog::browseTTSDictDir);
    connect(browseDataBtn, &QPushButton::clicked, this, &ModelSettingsDialog::browseTTSDataDir);
}

void ModelSettingsDialog::setupAdvancedTab() {
    advancedTab = new QWidget();
    tabWidget->addTab(advancedTab, "高级设置");
    
    auto* layout = new QVBoxLayout(advancedTab);
    
    // 路径设置组
    auto* pathGroup = new QGroupBox("路径设置", this);
    auto* pathLayout = new QGridLayout(pathGroup);
    
    pathLayout->addWidget(new QLabel("数据根目录:"), 0, 0);
    dataPathEdit = new QLineEdit(this);
    dataPathEdit->setText(getDefaultDataPath());
    auto* browseDataPathBtn = new QPushButton("浏览", this);
    pathLayout->addWidget(dataPathEdit, 0, 1);
    pathLayout->addWidget(browseDataPathBtn, 0, 2);
    
    layout->addWidget(pathGroup);
    
    // 功能设置组
    auto* featureGroup = new QGroupBox("功能设置", this);
    auto* featureLayout = new QVBoxLayout(featureGroup);
    
    autoScanCheckBox = new QCheckBox("启动时自动扫描模型", this);
    autoScanCheckBox->setChecked(true);
    featureLayout->addWidget(autoScanCheckBox);
    
    enableLoggingCheckBox = new QCheckBox("启用详细日志", this);
    enableLoggingCheckBox->setChecked(false);
    featureLayout->addWidget(enableLoggingCheckBox);
    
    layout->addWidget(featureGroup);
    
    layout->addStretch();
    
    // 连接信号
    connect(browseDataPathBtn, &QPushButton::clicked, [this]() {
        QString dir = QFileDialog::getExistingDirectory(this, "选择数据根目录", dataPathEdit->text());
        if (!dir.isEmpty()) {
            dataPathEdit->setText(dir);
        }
    });
}

void ModelSettingsDialog::connectSignals() {
    connect(offlineAsrModelCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), 
            this, &ModelSettingsDialog::onOfflineASRModelChanged);
    connect(onlineAsrModelCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), 
            this, &ModelSettingsDialog::onOnlineASRModelChanged);
    connect(kwsModelCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), 
            this, &ModelSettingsDialog::onKWSModelChanged);
    connect(ttsModelCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), 
            this, &ModelSettingsDialog::onTTSModelChanged);
    
    connect(offlineAsrModelPathEdit, &QLineEdit::textChanged, this, &ModelSettingsDialog::updateOfflineASRModelInfo);
    connect(onlineAsrModelPathEdit, &QLineEdit::textChanged, this, &ModelSettingsDialog::updateOnlineASRModelInfo);
    connect(kwsModelPathEdit, &QLineEdit::textChanged, this, &ModelSettingsDialog::updateKWSModelInfo);
    connect(ttsModelPathEdit, &QLineEdit::textChanged, this, &ModelSettingsDialog::updateTTSModelInfo);
    
    connect(testOfflineASRBtn, &QPushButton::clicked, this, &ModelSettingsDialog::testOfflineASRModel);
    connect(testOnlineASRBtn, &QPushButton::clicked, this, &ModelSettingsDialog::testOnlineASRModel);
    connect(testKWSBtn, &QPushButton::clicked, this, &ModelSettingsDialog::testKWSModel);
    connect(testTTSBtn, &QPushButton::clicked, this, &ModelSettingsDialog::testTTSModel);
    
    connect(saveBtn, &QPushButton::clicked, this, &ModelSettingsDialog::saveSettings);
    connect(cancelBtn, &QPushButton::clicked, this, &QDialog::reject);
    connect(resetBtn, &QPushButton::clicked, this, &ModelSettingsDialog::resetToDefaults);
    connect(scanBtn, &QPushButton::clicked, this, &ModelSettingsDialog::scanForModels);
}

QString ModelSettingsDialog::getDefaultDataPath() const {
    return QDir::homePath() + "/.config/QSmartAssistant/Data";
}

void ModelSettingsDialog::browseOfflineASRModel() {
    QString fileName = QFileDialog::getOpenFileName(this, "选择离线ASR模型文件", 
        offlineAsrModelPathEdit->text().isEmpty() ? getDefaultDataPath() : offlineAsrModelPathEdit->text(),
        "ONNX模型文件 (*.onnx)");
    if (!fileName.isEmpty()) {
        offlineAsrModelPathEdit->setText(fileName);
    }
}

void ModelSettingsDialog::browseOfflineASRTokens() {
    QString fileName = QFileDialog::getOpenFileName(this, "选择词汇表文件", 
        offlineAsrTokensPathEdit->text().isEmpty() ? getDefaultDataPath() : offlineAsrTokensPathEdit->text(),
        "文本文件 (*.txt)");
    if (!fileName.isEmpty()) {
        offlineAsrTokensPathEdit->setText(fileName);
    }
}

void ModelSettingsDialog::browseOnlineASRModel() {
    QString fileName = QFileDialog::getOpenFileName(this, "选择在线ASR编码器文件", 
        onlineAsrModelPathEdit->text().isEmpty() ? getDefaultDataPath() : onlineAsrModelPathEdit->text(),
        "ONNX模型文件 (*.onnx)");
    if (!fileName.isEmpty()) {
        onlineAsrModelPathEdit->setText(fileName);
    }
}

void ModelSettingsDialog::browseOnlineASRTokens() {
    QString fileName = QFileDialog::getOpenFileName(this, "选择词汇表文件", 
        onlineAsrTokensPathEdit->text().isEmpty() ? getDefaultDataPath() : onlineAsrTokensPathEdit->text(),
        "文本文件 (*.txt)");
    if (!fileName.isEmpty()) {
        onlineAsrTokensPathEdit->setText(fileName);
    }
}

void ModelSettingsDialog::browseKWSModel() {
    QString fileName = QFileDialog::getOpenFileName(this, "选择语音唤醒模型文件", 
        kwsModelPathEdit->text().isEmpty() ? getDefaultDataPath() : kwsModelPathEdit->text(),
        "ONNX模型文件 (*.onnx)");
    if (!fileName.isEmpty()) {
        kwsModelPathEdit->setText(fileName);
    }
}

void ModelSettingsDialog::browseKWSTokens() {
    QString fileName = QFileDialog::getOpenFileName(this, "选择词汇表文件", 
        kwsTokensPathEdit->text().isEmpty() ? getDefaultDataPath() : kwsTokensPathEdit->text(),
        "文本文件 (*.txt)");
    if (!fileName.isEmpty()) {
        kwsTokensPathEdit->setText(fileName);
    }
}

void ModelSettingsDialog::browseKWSKeywords() {
    QString fileName = QFileDialog::getOpenFileName(this, "选择关键词文件", 
        kwsKeywordsPathEdit->text().isEmpty() ? getDefaultDataPath() : kwsKeywordsPathEdit->text(),
        "文本文件 (*.txt)");
    if (!fileName.isEmpty()) {
        kwsKeywordsPathEdit->setText(fileName);
    }
}

void ModelSettingsDialog::browseTTSModel() {
    QString fileName = QFileDialog::getOpenFileName(this, "选择TTS模型文件", 
        ttsModelPathEdit->text().isEmpty() ? getDefaultDataPath() : ttsModelPathEdit->text(),
        "ONNX模型文件 (*.onnx)");
    if (!fileName.isEmpty()) {
        ttsModelPathEdit->setText(fileName);
    }
}

void ModelSettingsDialog::browseTTSTokens() {
    QString fileName = QFileDialog::getOpenFileName(this, "选择词汇表文件", 
        ttsTokensPathEdit->text().isEmpty() ? getDefaultDataPath() : ttsTokensPathEdit->text(),
        "文本文件 (*.txt)");
    if (!fileName.isEmpty()) {
        ttsTokensPathEdit->setText(fileName);
    }
}

void ModelSettingsDialog::browseTTSLexicon() {
    QString fileName = QFileDialog::getOpenFileName(this, "选择词典文件", 
        ttsLexiconPathEdit->text().isEmpty() ? getDefaultDataPath() : ttsLexiconPathEdit->text(),
        "文本文件 (*.txt)");
    if (!fileName.isEmpty()) {
        ttsLexiconPathEdit->setText(fileName);
    }
}

void ModelSettingsDialog::browseTTSDictDir() {
    QString dir = QFileDialog::getExistingDirectory(this, "选择字典目录", 
        ttsDictDirPathEdit->text().isEmpty() ? getDefaultDataPath() : ttsDictDirPathEdit->text());
    if (!dir.isEmpty()) {
        ttsDictDirPathEdit->setText(dir);
    }
}

void ModelSettingsDialog::browseTTSDataDir() {
    QString dir = QFileDialog::getExistingDirectory(this, "选择数据目录", 
        ttsDataDirPathEdit->text().isEmpty() ? getDefaultDataPath() : ttsDataDirPathEdit->text());
    if (!dir.isEmpty()) {
        ttsDataDirPathEdit->setText(dir);
    }
}

void ModelSettingsDialog::onOfflineASRModelChanged() {
    QString modelType = offlineAsrModelCombo->currentData().toString();
    QString dataPath = dataPathEdit->text();
    
    if (modelType == "paraformer-zh") {
        offlineAsrModelPathEdit->setText(dataPath + "/sherpa-onnx-paraformer-zh-2024-03-09/model.int8.onnx");
        offlineAsrTokensPathEdit->setText(dataPath + "/sherpa-onnx-paraformer-zh-2024-03-09/tokens.txt");
    } else if (modelType == "whisper-multilingual") {
        offlineAsrModelPathEdit->setText(dataPath + "/sherpa-onnx-whisper-base/base.onnx");
        offlineAsrTokensPathEdit->setText(dataPath + "/sherpa-onnx-whisper-base/base.tokens");
    }
    // 自定义模式不自动填充路径
}

void ModelSettingsDialog::onOnlineASRModelChanged() {
    QString modelType = onlineAsrModelCombo->currentData().toString();
    QString dataPath = dataPathEdit->text();
    
    if (modelType == "streaming-paraformer-zh-en") {
        onlineAsrModelPathEdit->setText(dataPath + "/sherpa-onnx-streaming-paraformer-bilingual-zh-en/encoder.int8.onnx");
        onlineAsrTokensPathEdit->setText(dataPath + "/sherpa-onnx-streaming-paraformer-bilingual-zh-en/tokens.txt");
    } else if (modelType == "streaming-zipformer-zh-en") {
        onlineAsrModelPathEdit->setText(dataPath + "/sherpa-onnx-streaming-zipformer-zh-en/encoder.onnx");
        onlineAsrTokensPathEdit->setText(dataPath + "/sherpa-onnx-streaming-zipformer-zh-en/tokens.txt");
    }
    // 自定义模式不自动填充路径
}

void ModelSettingsDialog::onKWSModelChanged() {
    QString modelType = kwsModelCombo->currentData().toString();
    QString dataPath = dataPathEdit->text();
    
    if (modelType == "zipformer-wenetspeech-3.3m") {
        kwsModelPathEdit->setText(dataPath + "/sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01/encoder-epoch-12-avg-2-chunk-16-left-64.onnx");
        kwsTokensPathEdit->setText(dataPath + "/sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01/tokens.txt");
        kwsKeywordsPathEdit->setText(dataPath + "/sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01/keywords.txt");
    } else if (modelType == "zipformer-gigaspeech") {
        kwsModelPathEdit->setText(dataPath + "/sherpa-onnx-kws-zipformer-gigaspeech/model.onnx");
        kwsTokensPathEdit->setText(dataPath + "/sherpa-onnx-kws-zipformer-gigaspeech/tokens.txt");
        kwsKeywordsPathEdit->setText(dataPath + "/sherpa-onnx-kws-zipformer-gigaspeech/keywords.txt");
    }
    // 自定义模式不自动填充路径
}

void ModelSettingsDialog::onTTSModelChanged() {
    QString modelType = ttsModelCombo->currentData().toString();
    QString dataPath = dataPathEdit->text();
    
    if (modelType == "melo-zh-en") {
        ttsModelPathEdit->setText(dataPath + "/vits-melo-tts-zh_en/model.int8.onnx");
        ttsTokensPathEdit->setText(dataPath + "/vits-melo-tts-zh_en/tokens.txt");
        ttsLexiconPathEdit->setText(dataPath + "/vits-melo-tts-zh_en/lexicon.txt");
        ttsDictDirPathEdit->setText(dataPath + "/vits-melo-tts-zh_en/dict");
        ttsDataDirPathEdit->clear();
    } else if (modelType == "vits-zh") {
        ttsModelPathEdit->setText(dataPath + "/vits-zh-aishell3/vits-aishell3.int8.onnx");
        ttsTokensPathEdit->setText(dataPath + "/vits-zh-aishell3/tokens.txt");
        ttsLexiconPathEdit->setText(dataPath + "/vits-zh-aishell3/lexicon.txt");
        ttsDictDirPathEdit->clear();
        ttsDataDirPathEdit->clear();
    }
    // 自定义模式不自动填充路径
}

void ModelSettingsDialog::updateOfflineASRModelInfo() {
    QString modelPath = offlineAsrModelPathEdit->text();
    if (modelPath.isEmpty()) {
        offlineAsrModelInfoEdit->clear();
        testOfflineASRBtn->setEnabled(false);
        return;
    }
    
    QFileInfo fileInfo(modelPath);
    if (fileInfo.exists()) {
        QString info = QString("文件大小: %1 MB\n修改时间: %2\n状态: 文件存在")
                      .arg(fileInfo.size() / 1024.0 / 1024.0, 0, 'f', 1)
                      .arg(fileInfo.lastModified().toString("yyyy-MM-dd hh:mm:ss"));
        offlineAsrModelInfoEdit->setText(info);
        testOfflineASRBtn->setEnabled(validateOfflineASRConfig());
    } else {
        offlineAsrModelInfoEdit->setText("状态: 文件不存在");
        testOfflineASRBtn->setEnabled(false);
    }
}

void ModelSettingsDialog::updateOnlineASRModelInfo() {
    QString modelPath = onlineAsrModelPathEdit->text();
    if (modelPath.isEmpty()) {
        onlineAsrModelInfoEdit->clear();
        testOnlineASRBtn->setEnabled(false);
        return;
    }
    
    QFileInfo fileInfo(modelPath);
    if (fileInfo.exists()) {
        QString info = QString("文件大小: %1 MB\n修改时间: %2\n状态: 文件存在")
                      .arg(fileInfo.size() / 1024.0 / 1024.0, 0, 'f', 1)
                      .arg(fileInfo.lastModified().toString("yyyy-MM-dd hh:mm:ss"));
        onlineAsrModelInfoEdit->setText(info);
        testOnlineASRBtn->setEnabled(validateOnlineASRConfig());
    } else {
        onlineAsrModelInfoEdit->setText("状态: 文件不存在");
        testOnlineASRBtn->setEnabled(false);
    }
}

void ModelSettingsDialog::updateKWSModelInfo() {
    QString modelPath = kwsModelPathEdit->text();
    if (modelPath.isEmpty()) {
        kwsModelInfoEdit->clear();
        testKWSBtn->setEnabled(false);
        return;
    }
    
    QFileInfo fileInfo(modelPath);
    if (fileInfo.exists()) {
        QString info = QString("文件大小: %1 MB\n修改时间: %2\n状态: 文件存在")
                      .arg(fileInfo.size() / 1024.0 / 1024.0, 0, 'f', 1)
                      .arg(fileInfo.lastModified().toString("yyyy-MM-dd hh:mm:ss"));
        kwsModelInfoEdit->setText(info);
        testKWSBtn->setEnabled(validateKWSConfig());
    } else {
        kwsModelInfoEdit->setText("状态: 文件不存在");
        testKWSBtn->setEnabled(false);
    }
}

void ModelSettingsDialog::updateTTSModelInfo() {
    QString modelPath = ttsModelPathEdit->text();
    if (modelPath.isEmpty()) {
        ttsModelInfoEdit->clear();
        testTTSBtn->setEnabled(false);
        return;
    }
    
    QFileInfo fileInfo(modelPath);
    if (fileInfo.exists()) {
        QString info = QString("文件大小: %1 MB\n修改时间: %2\n状态: 文件存在")
                      .arg(fileInfo.size() / 1024.0 / 1024.0, 0, 'f', 1)
                      .arg(fileInfo.lastModified().toString("yyyy-MM-dd hh:mm:ss"));
        ttsModelInfoEdit->setText(info);
        testTTSBtn->setEnabled(validateTTSConfig());
    } else {
        ttsModelInfoEdit->setText("状态: 文件不存在");
        testTTSBtn->setEnabled(false);
    }
}

bool ModelSettingsDialog::validateOfflineASRConfig() const {
    return QFileInfo::exists(offlineAsrModelPathEdit->text()) && 
           QFileInfo::exists(offlineAsrTokensPathEdit->text());
}

bool ModelSettingsDialog::validateOnlineASRConfig() const {
    return QFileInfo::exists(onlineAsrModelPathEdit->text()) && 
           QFileInfo::exists(onlineAsrTokensPathEdit->text());
}

bool ModelSettingsDialog::validateKWSConfig() const {
    return QFileInfo::exists(kwsModelPathEdit->text()) && 
           QFileInfo::exists(kwsTokensPathEdit->text()) &&
           QFileInfo::exists(kwsKeywordsPathEdit->text());
}

bool ModelSettingsDialog::validateTTSConfig() const {
    return QFileInfo::exists(ttsModelPathEdit->text()) && 
           QFileInfo::exists(ttsTokensPathEdit->text()) &&
           QFileInfo::exists(ttsLexiconPathEdit->text());
}

void ModelSettingsDialog::testOfflineASRModel() {
    QMessageBox::information(this, "测试离线ASR模型", "离线ASR模型测试功能待实现");
}

void ModelSettingsDialog::testOnlineASRModel() {
    QMessageBox::information(this, "测试在线ASR模型", "在线ASR模型测试功能待实现");
}

void ModelSettingsDialog::testKWSModel() {
    QMessageBox::information(this, "测试语音唤醒模型", "语音唤醒模型测试功能待实现");
}

void ModelSettingsDialog::testTTSModel() {
    QMessageBox::information(this, "测试TTS模型", "TTS模型测试功能待实现");
}

void ModelSettingsDialog::saveSettings() {
    // 保存离线ASR设置
    settings->beginGroup("OfflineASR");
    settings->setValue("modelPath", offlineAsrModelPathEdit->text());
    settings->setValue("tokensPath", offlineAsrTokensPathEdit->text());
    settings->setValue("modelType", offlineAsrModelCombo->currentData().toString());
    settings->endGroup();
    
    // 保存在线ASR设置
    settings->beginGroup("OnlineASR");
    settings->setValue("modelPath", onlineAsrModelPathEdit->text());
    settings->setValue("tokensPath", onlineAsrTokensPathEdit->text());
    settings->setValue("modelType", onlineAsrModelCombo->currentData().toString());
    settings->endGroup();
    
    // 保存语音唤醒设置
    settings->beginGroup("KWS");
    settings->setValue("modelPath", kwsModelPathEdit->text());
    settings->setValue("tokensPath", kwsTokensPathEdit->text());
    settings->setValue("keywordsPath", kwsKeywordsPathEdit->text());
    settings->setValue("modelType", kwsModelCombo->currentData().toString());
    
    // 保存KWS参数
    KWSParams params = getCurrentKWSParams();
    settings->setValue("threshold", params.threshold);
    settings->setValue("maxActivePaths", params.maxActivePaths);
    settings->setValue("numTrailingBlanks", params.numTrailingBlanks);
    settings->setValue("keywordsScore", params.keywordsScore);
    settings->setValue("numThreads", params.numThreads);
    settings->endGroup();
    
    // 保存TTS设置
    settings->beginGroup("TTS");
    settings->setValue("modelPath", ttsModelPathEdit->text());
    settings->setValue("tokensPath", ttsTokensPathEdit->text());
    settings->setValue("lexiconPath", ttsLexiconPathEdit->text());
    settings->setValue("dictDirPath", ttsDictDirPathEdit->text());
    settings->setValue("dataDirPath", ttsDataDirPathEdit->text());
    settings->setValue("modelType", ttsModelCombo->currentData().toString());
    settings->endGroup();
    
    // 保存高级设置
    settings->beginGroup("Advanced");
    settings->setValue("dataPath", dataPathEdit->text());
    settings->setValue("autoScan", autoScanCheckBox->isChecked());
    settings->setValue("enableLogging", enableLoggingCheckBox->isChecked());
    settings->endGroup();
    
    emit modelsChanged();
    accept();
}

void ModelSettingsDialog::loadSettings() {
    // 加载离线ASR设置
    settings->beginGroup("OfflineASR");
    offlineAsrModelPathEdit->setText(settings->value("modelPath").toString());
    offlineAsrTokensPathEdit->setText(settings->value("tokensPath").toString());
    QString offlineAsrModelType = settings->value("modelType", "paraformer-zh").toString();
    int offlineAsrIndex = offlineAsrModelCombo->findData(offlineAsrModelType);
    if (offlineAsrIndex >= 0) offlineAsrModelCombo->setCurrentIndex(offlineAsrIndex);
    settings->endGroup();
    
    // 加载在线ASR设置
    settings->beginGroup("OnlineASR");
    onlineAsrModelPathEdit->setText(settings->value("modelPath").toString());
    onlineAsrTokensPathEdit->setText(settings->value("tokensPath").toString());
    QString onlineAsrModelType = settings->value("modelType", "streaming-paraformer-zh-en").toString();
    int onlineAsrIndex = onlineAsrModelCombo->findData(onlineAsrModelType);
    if (onlineAsrIndex >= 0) onlineAsrModelCombo->setCurrentIndex(onlineAsrIndex);
    settings->endGroup();
    
    // 加载语音唤醒设置
    settings->beginGroup("KWS");
    kwsModelPathEdit->setText(settings->value("modelPath").toString());
    kwsTokensPathEdit->setText(settings->value("tokensPath").toString());
    kwsKeywordsPathEdit->setText(settings->value("keywordsPath").toString());
    QString kwsModelType = settings->value("modelType", "zipformer-wenetspeech-3.3m").toString();
    int kwsIndex = kwsModelCombo->findData(kwsModelType);
    if (kwsIndex >= 0) kwsModelCombo->setCurrentIndex(kwsIndex);
    
    // 加载KWS参数
    KWSParams params;
    params.threshold = settings->value("threshold", 0.25f).toFloat();
    params.maxActivePaths = settings->value("maxActivePaths", 8).toInt();
    params.numTrailingBlanks = settings->value("numTrailingBlanks", 2).toInt();
    params.keywordsScore = settings->value("keywordsScore", 1.5f).toFloat();
    params.numThreads = settings->value("numThreads", 2).toInt();
    setCurrentKWSParams(params);
    settings->endGroup();
    
    // 加载TTS设置
    settings->beginGroup("TTS");
    ttsModelPathEdit->setText(settings->value("modelPath").toString());
    ttsTokensPathEdit->setText(settings->value("tokensPath").toString());
    ttsLexiconPathEdit->setText(settings->value("lexiconPath").toString());
    ttsDictDirPathEdit->setText(settings->value("dictDirPath").toString());
    ttsDataDirPathEdit->setText(settings->value("dataDirPath").toString());
    QString ttsModelType = settings->value("modelType", "melo-zh-en").toString();
    int ttsIndex = ttsModelCombo->findData(ttsModelType);
    if (ttsIndex >= 0) ttsModelCombo->setCurrentIndex(ttsIndex);
    settings->endGroup();
    
    // 加载高级设置
    settings->beginGroup("Advanced");
    dataPathEdit->setText(settings->value("dataPath", getDefaultDataPath()).toString());
    autoScanCheckBox->setChecked(settings->value("autoScan", true).toBool());
    enableLoggingCheckBox->setChecked(settings->value("enableLogging", false).toBool());
    settings->endGroup();
    
    // 如果没有保存的设置，使用默认值
    if (offlineAsrModelPathEdit->text().isEmpty()) {
        onOfflineASRModelChanged();
    }
    if (onlineAsrModelPathEdit->text().isEmpty()) {
        onOnlineASRModelChanged();
    }
    if (kwsModelPathEdit->text().isEmpty()) {
        onKWSModelChanged();
    }
    if (ttsModelPathEdit->text().isEmpty()) {
        onTTSModelChanged();
    }
}

void ModelSettingsDialog::resetToDefaults() {
    int ret = QMessageBox::question(this, "重置设置", 
        "确定要重置所有设置为默认值吗？这将清除当前的所有配置。",
        QMessageBox::Yes | QMessageBox::No);
    
    if (ret == QMessageBox::Yes) {
        // 重置为默认值
        offlineAsrModelCombo->setCurrentIndex(1); // paraformer-zh
        onlineAsrModelCombo->setCurrentIndex(1); // streaming-paraformer-zh-en
        kwsModelCombo->setCurrentIndex(1); // zipformer-wenetspeech-3.3m
        ttsModelCombo->setCurrentIndex(1); // melo-zh-en
        dataPathEdit->setText(getDefaultDataPath());
        autoScanCheckBox->setChecked(true);
        enableLoggingCheckBox->setChecked(false);
        
        onOfflineASRModelChanged();
        onOnlineASRModelChanged();
        onKWSModelChanged();
        onTTSModelChanged();
    }
}

void ModelSettingsDialog::scanForModels() {
    QMessageBox::information(this, "扫描模型", "模型扫描功能待实现");
}

ModelConfig ModelSettingsDialog::getCurrentOfflineASRConfig() const {
    ModelConfig config;
    config.name = offlineAsrModelCombo->currentText();
    config.modelPath = offlineAsrModelPathEdit->text();
    config.tokensPath = offlineAsrTokensPathEdit->text();
    config.isEnabled = validateOfflineASRConfig();
    return config;
}

ModelConfig ModelSettingsDialog::getCurrentOnlineASRConfig() const {
    ModelConfig config;
    config.name = onlineAsrModelCombo->currentText();
    config.modelPath = onlineAsrModelPathEdit->text();
    config.tokensPath = onlineAsrTokensPathEdit->text();
    config.isEnabled = validateOnlineASRConfig();
    return config;
}

ModelConfig ModelSettingsDialog::getCurrentKWSConfig() const {
    ModelConfig config;
    config.name = kwsModelCombo->currentText();
    config.modelPath = kwsModelPathEdit->text();
    config.tokensPath = kwsTokensPathEdit->text();
    config.lexiconPath = kwsKeywordsPathEdit->text(); // 使用lexiconPath存储关键词文件路径
    config.isEnabled = validateKWSConfig();
    return config;
}

ModelConfig ModelSettingsDialog::getCurrentTTSConfig() const {
    ModelConfig config;
    config.name = ttsModelCombo->currentText();
    config.modelPath = ttsModelPathEdit->text();
    config.tokensPath = ttsTokensPathEdit->text();
    config.lexiconPath = ttsLexiconPathEdit->text();
    config.dictDirPath = ttsDictDirPathEdit->text();
    config.dataDirPath = ttsDataDirPathEdit->text();
    config.isEnabled = validateTTSConfig();
    return config;
}

void ModelSettingsDialog::setCurrentOfflineASRConfig(const ModelConfig& config) {
    offlineAsrModelPathEdit->setText(config.modelPath);
    offlineAsrTokensPathEdit->setText(config.tokensPath);
}

void ModelSettingsDialog::setCurrentOnlineASRConfig(const ModelConfig& config) {
    onlineAsrModelPathEdit->setText(config.modelPath);
    onlineAsrTokensPathEdit->setText(config.tokensPath);
}

void ModelSettingsDialog::setCurrentKWSConfig(const ModelConfig& config) {
    kwsModelPathEdit->setText(config.modelPath);
    kwsTokensPathEdit->setText(config.tokensPath);
    kwsKeywordsPathEdit->setText(config.lexiconPath); // 从lexiconPath读取关键词文件路径
}

void ModelSettingsDialog::setCurrentTTSConfig(const ModelConfig& config) {
    ttsModelPathEdit->setText(config.modelPath);
    ttsTokensPathEdit->setText(config.tokensPath);
    ttsLexiconPathEdit->setText(config.lexiconPath);
    ttsDictDirPathEdit->setText(config.dictDirPath);
    ttsDataDirPathEdit->setText(config.dataDirPath);
}
// KWS参数相关方法实现
ModelSettingsDialog::KWSParams ModelSettingsDialog::getCurrentKWSParams() const {
    KWSParams params;
    
    bool ok;
    params.threshold = kwsThresholdEdit->text().toFloat(&ok);
    if (!ok || params.threshold < 0.01f || params.threshold > 1.0f) {
        params.threshold = 0.25f; // 默认值
    }
    
    params.maxActivePaths = kwsMaxActivePathsEdit->text().toInt(&ok);
    if (!ok || params.maxActivePaths < 1 || params.maxActivePaths > 16) {
        params.maxActivePaths = 8; // 默认值
    }
    
    params.numTrailingBlanks = kwsTrailingBlanksEdit->text().toInt(&ok);
    if (!ok || params.numTrailingBlanks < 1 || params.numTrailingBlanks > 5) {
        params.numTrailingBlanks = 2; // 默认值
    }
    
    params.keywordsScore = kwsKeywordsScoreEdit->text().toFloat(&ok);
    if (!ok || params.keywordsScore < 0.5f || params.keywordsScore > 3.0f) {
        params.keywordsScore = 1.5f; // 默认值
    }
    
    params.numThreads = kwsNumThreadsEdit->text().toInt(&ok);
    if (!ok || params.numThreads < 1 || params.numThreads > 4) {
        params.numThreads = 2; // 默认值
    }
    
    return params;
}

void ModelSettingsDialog::setCurrentKWSParams(const KWSParams& params) {
    kwsThresholdEdit->setText(QString::number(params.threshold, 'f', 2));
    kwsMaxActivePathsEdit->setText(QString::number(params.maxActivePaths));
    kwsTrailingBlanksEdit->setText(QString::number(params.numTrailingBlanks));
    kwsKeywordsScoreEdit->setText(QString::number(params.keywordsScore, 'f', 1));
    kwsNumThreadsEdit->setText(QString::number(params.numThreads));
}

void ModelSettingsDialog::onKWSParamsChanged() {
    // 实时验证参数
    validateKWSParams();
}

void ModelSettingsDialog::resetKWSParams() {
    int ret = QMessageBox::question(this, "重置KWS参数", 
        "确定要重置KWS参数为推荐的默认值吗？",
        QMessageBox::Yes | QMessageBox::No);
    
    if (ret == QMessageBox::Yes) {
        KWSParams defaultParams; // 使用默认构造函数的默认值
        setCurrentKWSParams(defaultParams);
        
        QMessageBox::information(this, "参数重置", 
            "KWS参数已重置为默认值。\n"
            "请保存设置并重启KWS检测以使新参数生效。");
    }
}

void ModelSettingsDialog::validateKWSParams() {
    QString errorMsg;
    bool hasError = false;
    
    // 验证阈值
    bool ok;
    float threshold = kwsThresholdEdit->text().toFloat(&ok);
    if (!ok || threshold < 0.01f || threshold > 1.0f) {
        errorMsg += "• 关键词阈值必须在0.01-1.0范围内\n";
        hasError = true;
        kwsThresholdEdit->setStyleSheet("QLineEdit { border: 2px solid red; }");
    } else {
        kwsThresholdEdit->setStyleSheet("");
    }
    
    // 验证最大活跃路径数
    int maxActivePaths = kwsMaxActivePathsEdit->text().toInt(&ok);
    if (!ok || maxActivePaths < 1 || maxActivePaths > 16) {
        errorMsg += "• 最大活跃路径数必须在1-16范围内\n";
        hasError = true;
        kwsMaxActivePathsEdit->setStyleSheet("QLineEdit { border: 2px solid red; }");
    } else {
        kwsMaxActivePathsEdit->setStyleSheet("");
    }
    
    // 验证尾随空白数
    int numTrailingBlanks = kwsTrailingBlanksEdit->text().toInt(&ok);
    if (!ok || numTrailingBlanks < 1 || numTrailingBlanks > 5) {
        errorMsg += "• 尾随空白数必须在1-5范围内\n";
        hasError = true;
        kwsTrailingBlanksEdit->setStyleSheet("QLineEdit { border: 2px solid red; }");
    } else {
        kwsTrailingBlanksEdit->setStyleSheet("");
    }
    
    // 验证关键词分数权重
    float keywordsScore = kwsKeywordsScoreEdit->text().toFloat(&ok);
    if (!ok || keywordsScore < 0.5f || keywordsScore > 3.0f) {
        errorMsg += "• 关键词分数权重必须在0.5-3.0范围内\n";
        hasError = true;
        kwsKeywordsScoreEdit->setStyleSheet("QLineEdit { border: 2px solid red; }");
    } else {
        kwsKeywordsScoreEdit->setStyleSheet("");
    }
    
    // 验证线程数
    int numThreads = kwsNumThreadsEdit->text().toInt(&ok);
    if (!ok || numThreads < 1 || numThreads > 4) {
        errorMsg += "• 处理线程数必须在1-4范围内\n";
        hasError = true;
        kwsNumThreadsEdit->setStyleSheet("QLineEdit { border: 2px solid red; }");
    } else {
        kwsNumThreadsEdit->setStyleSheet("");
    }
    
    // 更新保存按钮状态
    if (saveBtn) {
        saveBtn->setEnabled(!hasError);
        if (hasError) {
            saveBtn->setToolTip("请修正参数错误后再保存:\n" + errorMsg);
        } else {
            saveBtn->setToolTip("保存所有设置");
        }
    }
}