<template>
  <div class="app-container">
    <el-card>
      <div slot="header" class="card-header">
        <span>AI模型配置管理</span>
        <div>
          <el-button type="primary" size="small" @click="handleAddModel" v-if="activeTab === 'models'">
            <i class="el-icon-plus"></i>新增模型
          </el-button>
          <el-button type="success" size="small" @click="handleRefresh">
            <i class="el-icon-refresh"></i>刷新缓存
          </el-button>
        </div>
      </div>

      <el-alert
        title="统一模型配置说明"
        description="所有文本AI模型统一在此管理，按sort_order排序优先级（越小越优先）。每个场景可独立配置使用哪些模型及流水线顺序。FastGPT、TTS语音、豆包视觉及图像/语音相关模型不在此处管理。"
        type="info" show-icon :closable="false" style="margin-bottom: 20px"
      />

      <el-tabs v-model="activeTab" @tab-click="handleTabClick">
        <!-- ===== 模型列表 Tab ===== -->
        <el-tab-pane label="模型列表" name="models">
          <el-table :data="modelList" v-loading="modelLoading" border size="small" row-key="id"
            style="width:100%">
            <el-table-column label="排序" width="70" align="center">
              <template slot-scope="{ row, $index }">
                <span class="sort-handle" style="cursor: move; font-size: 18px;">☰</span>
                <span style="margin-left: 4px;">{{ $index + 1 }}</span>
              </template>
            </el-table-column>
            <el-table-column prop="modelName" label="模型名称" min-width="120" />
            <el-table-column prop="providerCode" label="供应商" width="90" />
            <el-table-column prop="modelIdentifier" label="模型标识" min-width="160" show-overflow-tooltip />
            <el-table-column prop="apiEndpoint" label="API地址" min-width="200" show-overflow-tooltip />
            <el-table-column prop="maxTokens" label="MaxToken" width="90" align="center" />
            <el-table-column prop="temperature" label="温度" width="70" align="center" />
            <el-table-column prop="sortOrder" label="排序号" width="70" align="center" />
            <el-table-column prop="status" label="状态" width="70" align="center">
              <template slot-scope="{ row }">
                <el-tag :type="row.status === 1 ? 'success' : 'danger'" size="small">
                  {{ row.status === 1 ? '启用' : '禁用' }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column label="操作" width="280" fixed="right">
              <template slot-scope="{ row }">
                <el-button type="primary" size="mini" @click="handleEditModel(row)">编辑</el-button>
                <el-button type="success" size="mini" @click="handleTestModel(row)">测试</el-button>
                <el-popconfirm title="确定删除该模型吗？" @confirm="handleDeleteModel(row)">
                  <el-button slot="reference" type="danger" size="mini">删除</el-button>
                </el-popconfirm>
              </template>
            </el-table-column>
          </el-table>

          <div style="margin-top: 12px; text-align: right;">
            <el-button type="warning" size="small" @click="handleSaveSort" :disabled="!sortChanged">
              <i class="el-icon-sort"></i>保存排序
            </el-button>
          </div>
        </el-tab-pane>

        <!-- ===== 场景配置 Tab ===== -->
        <el-tab-pane label="场景配置" name="scenes">
          <el-row :gutter="16">
            <!-- 左侧：场景列表 -->
            <el-col :span="8">
              <el-card shadow="never" class="scene-list-card">
                <div slot="header" class="sub-header">使用场景</div>
                <div v-loading="sceneLoading">
                  <div v-for="scene in sceneList" :key="scene.sceneCode"
                    class="scene-item"
                    :class="{ active: selectedScene === scene.sceneCode }"
                    @click="selectScene(scene)">
                    <div class="scene-name">
                      {{ scene.sceneName }}
                      <el-tag v-if="scene.sceneType === 'multi_pipeline'" size="mini" type="warning" style="margin-left: 6px;">多模型</el-tag>
                    </div>
                    <div class="scene-code">{{ scene.sceneCode }}</div>
                  </div>
                </div>
              </el-card>
            </el-col>

            <!-- 右侧：场景详情 -->
            <el-col :span="16">
              <el-card shadow="never" v-if="selectedSceneInfo">
                <div slot="header" class="sub-header">
                  {{ selectedSceneInfo.sceneName }} - 模型配置
                  <el-tag size="small" :type="selectedSceneInfo.status === 1 ? 'success' : 'danger'" style="margin-left: 8px;">
                    {{ selectedSceneInfo.status === 1 ? '启用' : '禁用' }}
                  </el-tag>
                </div>

                <!-- 场景基础信息 -->
                <el-form :model="sceneForm" label-width="100px" size="small" inline>
                  <el-form-item label="场景编码">{{ selectedSceneInfo.sceneCode }}</el-form-item>
                  <el-form-item label="流水线类型" v-if="selectedSceneInfo.sceneType === 'multi_pipeline'">
                    {{ selectedSceneInfo.pipelineType === 'scoring' ? '质量评分链' : selectedSceneInfo.pipelineType === 'sequential' ? '顺序调用' : '-' }}
                  </el-form-item>
                  <el-form-item label="质量阈值" v-if="selectedSceneInfo.pipelineType === 'scoring'">
                    <el-input-number v-model="sceneForm.qualityThreshold" :min="60" :max="160" :step="10" size="mini" style="width: 100px;" />
                    <el-button type="primary" size="mini" @click="saveThreshold" style="margin-left: 8px;">保存</el-button>
                  </el-form-item>
                </el-form>

                <el-divider />

                <!-- 场景关联模型列表 -->
                <div style="margin-bottom: 10px; display: flex; justify-content: space-between; align-items: center;">
                  <span>关联模型流水线（按 pipeline_order 排序）</span>
                  <el-button type="primary" size="mini" @click="handleBindModel">
                    <i class="el-icon-plus"></i>绑定模型
                  </el-button>
                </div>

                <el-table :data="sceneModelList" v-loading="sceneModelLoading" border size="small"
                  row-key="id" style="width:100%">
                  <el-table-column label="顺序" width="60" align="center">
                    <template slot-scope="{ $index }">
                      <span class="sort-handle" style="cursor: move;">☰</span>
                      <span style="margin-left: 4px;">{{ $index + 1 }}</span>
                    </template>
                  </el-table-column>
                  <el-table-column label="模型名称" min-width="120">
                    <template slot-scope="{ row }">
                      {{ row.model ? row.model.modelName : '模型#' + row.modelId }}
                    </template>
                  </el-table-column>
                  <el-table-column label="供应商" width="80">
                    <template slot-scope="{ row }">
                      {{ row.model ? row.model.providerCode : '-' }}
                    </template>
                  </el-table-column>
                  <el-table-column label="流水线角色" width="110" align="center">
                    <template slot-scope="{ row }">
                      <el-tag size="mini" :type="row.role === 'scorer' ? 'warning' : 'success'">
                        {{ row.role === 'scorer' ? '评分者' : '生成者' }}
                      </el-tag>
                    </template>
                  </el-table-column>
                  <el-table-column prop="pipelineOrder" label="顺序号" width="70" align="center" />
                  <el-table-column prop="sortWeight" label="权重" width="60" align="center" />
                  <el-table-column label="操作" width="120" fixed="right">
                    <template slot-scope="{ row }">
                      <el-button type="text" size="mini" @click="handleEditSceneModel(row)">编辑</el-button>
                      <el-popconfirm title="确定移除此关联？" @confirm="handleRemoveSceneModel(row)">
                        <el-button slot="reference" type="text" size="mini" style="color: #F56C6C;">移除</el-button>
                      </el-popconfirm>
                    </template>
                  </el-table-column>
                </el-table>
                <div v-if="sceneModelList.length === 0" style="text-align: center; color: #999; padding: 40px 0;">
                  暂未绑定模型，请点击"绑定模型"添加
                </div>
              </el-card>

              <el-empty v-else description="请从左侧选择一个场景" />
            </el-col>
          </el-row>
        </el-tab-pane>
      </el-tabs>
    </el-card>

    <!-- 模型编辑弹窗 -->
    <el-dialog :title="modelDialogTitle" :visible.sync="modelDialogVisible" width="560px" @closed="resetModelForm">
      <el-form :model="modelForm" :rules="modelRules" ref="modelFormRef" label-width="120px">
        <el-form-item label="模型名称" prop="modelName">
          <el-input v-model="modelForm.modelName" placeholder="如：豆包Pro 32K" />
        </el-form-item>
        <el-form-item label="供应商" prop="providerCode">
          <el-select v-model="modelForm.providerCode" placeholder="请选择" style="width: 100%">
            <el-option label="豆包(Doubao)" value="doubao" />
            <el-option label="通义千问(Qwen)" value="qwen" />
            <el-option label="元宝(Yuanbao)" value="yuanbao" />
            <el-option label="DeepSeek" value="deepseek" />
          </el-select>
        </el-form-item>
        <el-form-item label="模型标识" prop="modelIdentifier">
          <el-input v-model="modelForm.modelIdentifier" placeholder="如：doubao-1-5-pro-32k" />
        </el-form-item>
        <el-form-item label="API地址" prop="apiEndpoint">
          <el-input v-model="modelForm.apiEndpoint" placeholder="API Endpoint" />
        </el-form-item>
        <el-form-item label="API Key" prop="apiKey">
          <el-input v-model="modelForm.apiKey" placeholder="API Key" show-password />
        </el-form-item>
        <el-form-item label="最大Token">
          <el-input-number v-model="modelForm.maxTokens" :min="512" :max="131072" :step="512" style="width: 180px;" />
        </el-form-item>
        <el-form-item label="温度参数">
          <el-slider v-model="modelForm.temperature" :min="0" :max="2" :step="0.1" show-input style="width: 200px;" />
        </el-form-item>
        <el-form-item label="排序号">
          <el-input-number v-model="modelForm.sortOrder" :min="0" :max="9999" style="width: 180px;" />
          <span style="color: #909399; font-size: 12px; margin-left: 8px;">越小越优先</span>
        </el-form-item>
        <el-form-item label="状态">
          <el-switch v-model="modelForm.status" :active-value="1" :inactive-value="0" />
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button @click="modelDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleSubmitModel">确定</el-button>
      </div>
    </el-dialog>

    <!-- 场景绑定模型弹窗 -->
    <el-dialog title="绑定模型到场景" :visible.sync="bindDialogVisible" width="480px">
      <el-form label-width="100px" size="small">
        <el-form-item label="选择模型">
          <el-select v-model="bindForm.modelId" placeholder="请选择模型" style="width: 100%" filterable>
            <el-option v-for="m in modelList" :key="m.id"
              :label="m.modelName + ' (' + m.providerCode + ')'" :value="m.id"
              :disabled="m.status !== 1" />
          </el-select>
        </el-form-item>
        <el-form-item label="流水线角色">
          <el-radio-group v-model="bindForm.role">
            <el-radio label="generator">生成者</el-radio>
            <el-radio label="scorer">评分者</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="流水线顺序">
          <el-input-number v-model="bindForm.pipelineOrder" :min="0" :max="99" size="small" />
        </el-form-item>
        <el-form-item label="权重">
          <el-input-number v-model="bindForm.sortWeight" :min="0" :max="99" size="small" />
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button @click="bindDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleConfirmBind">确定</el-button>
      </div>
    </el-dialog>

    <!-- 场景模型编辑弹窗 -->
    <el-dialog title="编辑场景模型" :visible.sync="editSceneModelDialog" width="420px">
      <el-form label-width="100px" size="small">
        <el-form-item label="流水线角色">
          <el-radio-group v-model="editSceneModelForm.role">
            <el-radio label="generator">生成者</el-radio>
            <el-radio label="scorer">评分者</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="流水线顺序">
          <el-input-number v-model="editSceneModelForm.pipelineOrder" :min="0" :max="99" size="small" />
        </el-form-item>
        <el-form-item label="权重">
          <el-input-number v-model="editSceneModelForm.sortWeight" :min="0" :max="99" size="small" />
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button @click="editSceneModelDialog = false">取消</el-button>
        <el-button type="primary" @click="handleUpdateSceneModel">确定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {
  listAiModel, getAiModel, addAiModel, updateAiModel, deleteAiModel,
  batchSortAiModel, testAiModel, refreshAiModel,
  listAiScene, updateAiScene, updateSceneThreshold,
  getSceneModels, addSceneModel, deleteSceneModel, updateSceneModel, refreshAiScene
} from '@/api/admin/aiModel'

export default {
  name: 'AiModelConfig',
  data() {
    return {
      activeTab: 'models',
      // 模型
      modelLoading: false,
      modelList: [],
      modelDialogVisible: false,
      modelDialogTitle: '',
      modelForm: {
        id: null, modelName: '', providerCode: '', modelIdentifier: '',
        apiEndpoint: '', apiKey: '', maxTokens: 4096, temperature: 0.7,
        sortOrder: 0, status: 1
      },
      modelRules: {
        modelName: [{ required: true, message: '请输入模型名称', trigger: 'blur' }],
        providerCode: [{ required: true, message: '请选择供应商', trigger: 'change' }],
        modelIdentifier: [{ required: true, message: '请输入模型标识', trigger: 'blur' }],
        apiEndpoint: [{ required: true, message: '请输入API地址', trigger: 'blur' }],
        apiKey: [{ required: true, message: '请输入API Key', trigger: 'blur' }]
      },
      sortChanged: false,
      // 场景
      sceneLoading: false,
      sceneList: [],
      selectedScene: '',
      selectedSceneInfo: null,
      sceneForm: { qualityThreshold: 120 },
      sceneModelLoading: false,
      sceneModelList: [],
      bindDialogVisible: false,
      bindForm: { modelId: null, role: 'generator', pipelineOrder: 0, sortWeight: 0 },
      editSceneModelDialog: false,
      editSceneModelForm: { id: null, role: 'generator', pipelineOrder: 0, sortWeight: 0 }
    }
  },
  created() {
    this.loadModels()
    this.loadScenes()
  },
  methods: {
    // ─── 模型 CRUD ───
    async loadModels() {
      this.modelLoading = true
      try {
        const res = await listAiModel()
        this.modelList = res.data || []
      } catch (e) {
        this.$message.error('获取模型列表失败')
      } finally {
        this.modelLoading = false
      }
    },
    handleAddModel() {
      this.modelDialogTitle = '新增模型'
      this.modelForm = {
        id: null, modelName: '', providerCode: '', modelIdentifier: '',
        apiEndpoint: '', apiKey: '', maxTokens: 4096, temperature: 0.7,
        sortOrder: 0, status: 1
      }
      this.modelDialogVisible = true
      this.$nextTick(() => { this.$refs.modelFormRef && this.$refs.modelFormRef.resetFields() })
    },
    handleEditModel(row) {
      this.modelDialogTitle = '编辑模型'
      this.modelForm = { ...row }
      this.modelDialogVisible = true
    },
    async handleSubmitModel() {
      try {
        await this.$refs.modelFormRef.validate()
        if (this.modelForm.id) {
          await updateAiModel(this.modelForm.id, this.modelForm)
          this.$message.success('修改成功')
        } else {
          await addAiModel(this.modelForm)
          this.$message.success('新增成功')
        }
        this.modelDialogVisible = false
        await this.loadModels()
      } catch (e) {
        if (e !== false) this.$message.error('操作失败')
      }
    },
    async handleDeleteModel(row) {
      try {
        await deleteAiModel(row.id)
        this.$message.success('删除成功')
        await this.loadModels()
      } catch (e) {
        this.$message.error('删除失败')
      }
    },
    async handleTestModel(row) {
      try {
        const res = await testAiModel(row.id)
        if (res.code === 200 && res.data) {
          const result = res.data
          if (result.success) {
            this.$message.success('连接成功！响应：' + (result.response || 'OK'))
          } else {
            this.$message.error('连接失败：' + (result.error || '未知错误'))
          }
        } else {
          this.$message.error('测试失败')
        }
      } catch (e) {
        this.$message.error('测试请求失败')
      }
    },
    handleSaveSort() {
      const sortList = this.modelList.map((m, i) => ({ id: m.id, sortOrder: i }))
      batchSortAiModel(sortList).then(() => {
        this.$message.success('排序已保存')
        this.sortChanged = false
        this.loadModels()
      }).catch(() => {
        this.$message.error('保存排序失败')
      })
    },
    resetModelForm() {
      this.modelForm = {
        id: null, modelName: '', providerCode: '', modelIdentifier: '',
        apiEndpoint: '', apiKey: '', maxTokens: 4096, temperature: 0.7,
        sortOrder: 0, status: 1
      }
    },

    // ─── 场景 ───
    async loadScenes() {
      this.sceneLoading = true
      try {
        const res = await listAiScene()
        this.sceneList = res.data || []
      } catch (e) {
        this.$message.error('获取场景列表失败')
      } finally {
        this.sceneLoading = false
      }
    },
    selectScene(scene) {
      this.selectedScene = scene.sceneCode
      this.selectedSceneInfo = scene
      this.sceneForm.qualityThreshold = scene.qualityThreshold || 120
      this.loadSceneModels(scene.sceneCode)
    },
    async loadSceneModels(sceneCode) {
      this.sceneModelLoading = true
      try {
        const res = await getSceneModels(sceneCode)
        this.sceneModelList = res.data || []
      } catch (e) {
        this.$message.error('获取场景模型列表失败')
      } finally {
        this.sceneModelLoading = false
      }
    },
    async saveThreshold() {
      try {
        await updateSceneThreshold(this.selectedScene, this.sceneForm.qualityThreshold)
        this.$message.success('阈值已更新')
        this.selectedSceneInfo.qualityThreshold = this.sceneForm.qualityThreshold
      } catch (e) {
        this.$message.error('更新失败')
      }
    },
    handleBindModel() {
      this.bindForm = { modelId: null, role: 'generator', pipelineOrder: this.sceneModelList.length, sortWeight: 0 }
      this.bindDialogVisible = true
    },
    async handleConfirmBind() {
      if (!this.bindForm.modelId) {
        this.$message.warning('请选择模型')
        return
      }
      try {
        await addSceneModel(this.selectedScene, this.bindForm)
        this.$message.success('绑定成功')
        this.bindDialogVisible = false
        this.loadSceneModels(this.selectedScene)
      } catch (e) {
        this.$message.error('绑定失败')
      }
    },
    handleEditSceneModel(row) {
      this.editSceneModelForm = {
        id: row.id,
        role: row.role || 'generator',
        pipelineOrder: row.pipelineOrder || 0,
        sortWeight: row.sortWeight || 0
      }
      this.editSceneModelDialog = true
    },
    async handleUpdateSceneModel() {
      try {
        await updateSceneModel(this.selectedScene, this.editSceneModelForm.id, this.editSceneModelForm)
        this.$message.success('更新成功')
        this.editSceneModelDialog = false
        this.loadSceneModels(this.selectedScene)
      } catch (e) {
        this.$message.error('更新失败')
      }
    },
    async handleRemoveSceneModel(row) {
      try {
        await deleteSceneModel(this.selectedScene, row.id)
        this.$message.success('已移除')
        this.loadSceneModels(this.selectedScene)
      } catch (e) {
        this.$message.error('移除失败')
      }
    },

    // ─── 通用 ───
    handleTabClick() {
      if (this.activeTab === 'models') this.loadModels()
      if (this.activeTab === 'scenes') this.loadScenes()
    },
    async handleRefresh() {
      try {
        await refreshAiModel()
        await refreshAiScene()
        this.$message.success('缓存已刷新')
        if (this.activeTab === 'models') this.loadModels()
        if (this.activeTab === 'scenes') this.loadScenes()
      } catch (e) {
        this.$message.error('刷新失败')
      }
    }
  }
}
</script>

<style scoped>
.card-header { display: flex; justify-content: space-between; align-items: center; }
.sub-header { font-weight: 600; font-size: 14px; }
.scene-list-card { max-height: 600px; overflow-y: auto; }
.scene-item {
  padding: 10px 12px;
  border: 1px solid #EBEEF5;
  border-radius: 4px;
  margin-bottom: 8px;
  cursor: pointer;
  transition: all 0.2s;
}
.scene-item:hover { border-color: #409EFF; background: #ECF5FF; }
.scene-item.active { border-color: #409EFF; background: #ECF5FF; }
.scene-name { font-weight: 500; font-size: 13px; }
.scene-code { color: #909399; font-size: 11px; margin-top: 2px; }
.sort-handle { cursor: move; color: #909399; display: inline-block; vertical-align: middle; }
.sort-handle:hover { color: #409EFF; }
</style>
