<template>
  <div class="page-content">
    <div class="mb-5 flex items-center justify-between gap-4">
      <div>
        <h2 class="text-xl font-semibold">模型供应商</h2>
        <p class="text-g-500 mt-1 text-sm">统一维护上游地址、能力和加密凭据</p>
      </div>
      <div class="flex gap-2">
        <ElButton :loading="rotating" @click="rotateCredentials">轮换凭据</ElButton>
        <ElButton type="primary" @click="openCreate">新增供应商</ElButton>
      </div>
    </div>

    <ElAlert
      class="mb-4"
      type="info"
      :closable="false"
      title="API Key 使用 AES-256-GCM 加密后写入 PostgreSQL，页面不会返回明文。"
    />

    <ElTable v-loading="loading" :data="providers" row-key="id">
      <ElTableColumn prop="code" label="代码" min-width="150" />
      <ElTableColumn prop="adapter" label="适配器" min-width="170" />
      <ElTableColumn prop="base_url" label="上游地址" min-width="260" show-overflow-tooltip />
      <ElTableColumn label="凭据" width="150">
        <template #default="{ row }">
          <span>{{ row.key_configured ? row.api_key_masked : '未配置' }}</span>
        </template>
      </ElTableColumn>
      <ElTableColumn label="状态" width="100">
        <template #default="{ row }">
          <ElTag :type="row.enabled ? 'success' : 'info'">{{ row.enabled ? '启用' : '停用' }}</ElTag>
        </template>
      </ElTableColumn>
      <ElTableColumn prop="revision" label="版本" width="90" />
      <ElTableColumn prop="credential_kek_version" label="KEK" width="80" />
      <ElTableColumn label="操作" width="270" fixed="right">
        <template #default="{ row }">
          <ElButton
            link
            type="success"
            :loading="testingId === row.id"
            @click="testConnection(row)"
          >
            测试
          </ElButton>
          <ElButton
            link
            type="warning"
            :loading="syncingId === row.id"
            @click="syncModels(row)"
          >
            同步模型
          </ElButton>
          <ElButton link type="primary" @click="showModels(row)">模型</ElButton>
          <ElButton link type="primary" @click="openEdit(row)">编辑</ElButton>
        </template>
      </ElTableColumn>
    </ElTable>

    <ElDialog v-model="dialogVisible" :title="editingId ? '编辑供应商' : '新增供应商'" width="620px">
      <ElForm ref="formRef" :model="form" :rules="rules" label-width="110px">
        <ElFormItem label="代码" prop="code">
          <ElInput v-model="form.code" placeholder="例如 openai" />
        </ElFormItem>
        <ElFormItem label="适配器" prop="adapter">
          <ElSelect v-model="form.adapter" class="w-full">
            <ElOption label="OpenAI Compatible" value="openai-compatible" />
          </ElSelect>
        </ElFormItem>
        <ElFormItem label="上游地址" prop="base_url">
          <ElInput v-model="form.base_url" placeholder="https://api.openai.com/v1" />
        </ElFormItem>
        <ElFormItem label="API Key">
          <ElInput
            v-model="form.api_key"
            type="password"
            show-password
            :placeholder="editingId ? '留空表示不更换' : '可留空'"
          />
        </ElFormItem>
        <ElFormItem label="能力">
          <ElSelect v-model="form.capabilities" multiple class="w-full">
            <ElOption v-for="item in capabilityOptions" :key="item" :label="item" :value="item" />
          </ElSelect>
        </ElFormItem>
        <ElFormItem label="启用">
          <ElSwitch v-model="form.enabled" />
        </ElFormItem>
        <ElFormItem label="默认供应商">
          <ElSwitch v-model="isDefault" />
        </ElFormItem>
      </ElForm>
      <template #footer>
        <ElButton @click="dialogVisible = false">取消</ElButton>
        <ElButton type="primary" :loading="saving" @click="submit">保存</ElButton>
      </template>
    </ElDialog>

    <ElDialog v-model="modelsVisible" :title="`${selectedProviderCode} 模型目录`" width="820px">
      <ElAlert
        class="mb-4"
        type="info"
        :closable="false"
        title="同步时不会删除历史模型；本次上游未返回的模型会被标记为停用。"
      />
      <ElTable v-loading="modelsLoading" :data="models" max-height="520">
        <ElTableColumn prop="provider_model_id" label="模型 ID" min-width="260" />
        <ElTableColumn prop="owned_by" label="所有者" min-width="140">
          <template #default="{ row }">{{ row.owned_by || '-' }}</template>
        </ElTableColumn>
        <ElTableColumn label="状态" width="90">
          <template #default="{ row }">
            <ElTag :type="row.enabled ? 'success' : 'info'">
              {{ row.enabled ? '可用' : '停用' }}
            </ElTag>
          </template>
        </ElTableColumn>
        <ElTableColumn label="最后发现" width="180">
          <template #default="{ row }">{{ formatTime(row.last_seen_at) }}</template>
        </ElTableColumn>
      </ElTable>
      <ElEmpty v-if="!modelsLoading && models.length === 0" description="尚未同步模型" />
    </ElDialog>
  </div>
</template>

<script setup lang="ts">
  import { ElMessage, ElMessageBox, FormInstance, FormRules } from 'element-plus'
  import {
    createProvider,
    fetchProviderModels,
    fetchProviders,
    ProviderInput,
    ProviderModel,
    ProviderRecord,
    rotateProviderCredentials,
    syncProviderModels,
    testProviderConnection,
    updateProvider
  } from '@/api/providers'

  const capabilityOptions = ['chat', 'responses', 'embeddings', 'models']
  const providers = ref<ProviderRecord[]>([])
  const loading = ref(false)
  const saving = ref(false)
  const rotating = ref(false)
  const testingId = ref('')
  const syncingId = ref('')
  const dialogVisible = ref(false)
  const modelsVisible = ref(false)
  const modelsLoading = ref(false)
  const selectedProviderCode = ref('')
  const models = ref<ProviderModel[]>([])
  const editingId = ref('')
  const isDefault = ref(false)
  const formRef = ref<FormInstance>()
  const form = reactive<ProviderInput>({
    code: '',
    adapter: 'openai-compatible',
    base_url: '',
    api_key: '',
    capabilities: [...capabilityOptions],
    config: {},
    enabled: true
  })
  const rules: FormRules = {
    code: [
      { required: true, message: '请输入代码', trigger: 'blur' },
      { pattern: /^[a-z][a-z0-9_-]{1,63}$/, message: '代码格式不正确', trigger: 'blur' }
    ],
    adapter: [{ required: true, message: '请选择适配器', trigger: 'change' }],
    base_url: [{ required: true, message: '请输入上游地址', trigger: 'blur' }]
  }

  function resetForm() {
    isDefault.value = false
    Object.assign(form, {
      code: '',
      adapter: 'openai-compatible',
      base_url: '',
      api_key: '',
      capabilities: [...capabilityOptions],
      config: {},
      enabled: true
    })
  }

  function openCreate() {
    editingId.value = ''
    resetForm()
    dialogVisible.value = true
  }

  function openEdit(record: ProviderRecord) {
    editingId.value = record.id
    isDefault.value = record.config.default === true
    Object.assign(form, {
      code: record.code,
      adapter: record.adapter,
      base_url: record.base_url,
      api_key: '',
      capabilities: [...record.capabilities],
      config: { ...record.config },
      enabled: record.enabled
    })
    dialogVisible.value = true
  }

  async function testConnection(record: ProviderRecord) {
    testingId.value = record.id
    try {
      const result = await testProviderConnection(record.id)
      const detail = result.status_code ? `HTTP ${result.status_code}，${result.latency_ms} ms` : `${result.latency_ms} ms`
      if (result.connected) ElMessage.success(`${result.message}（${detail}）`)
      else ElMessage.warning(`${result.message}（${detail}）`)
    } finally {
      testingId.value = ''
    }
  }

  async function syncModels(record: ProviderRecord) {
    syncingId.value = record.id
    try {
      const result = await syncProviderModels(record.id)
      ElMessage.success(
        `同步完成：发现 ${result.discovered}，可用 ${result.active}，停用 ${result.disabled}`
      )
      if (modelsVisible.value && selectedProviderCode.value === record.code) {
        await loadModels(record.id)
      }
    } finally {
      syncingId.value = ''
    }
  }

  async function showModels(record: ProviderRecord) {
    selectedProviderCode.value = record.code
    modelsVisible.value = true
    await loadModels(record.id)
  }

  async function loadModels(providerId: string) {
    modelsLoading.value = true
    try {
      models.value = await fetchProviderModels(providerId)
    } finally {
      modelsLoading.value = false
    }
  }

  function formatTime(value: string) {
    return value ? new Date(value).toLocaleString() : '-'
  }

  async function loadProviders() {
    loading.value = true
    try {
      providers.value = await fetchProviders()
    } finally {
      loading.value = false
    }
  }

  async function rotateCredentials() {
    try {
      await ElMessageBox.confirm(
        '将使用服务端当前活动 KEK 重新加密所有旧版本供应商凭据。请确认旧 KEK 已加载到 keyring。',
        '轮换供应商凭据',
        { type: 'warning', confirmButtonText: '开始轮换', cancelButtonText: '取消' }
      )
    } catch {
      return
    }
    rotating.value = true
    try {
      const result = await rotateProviderCredentials()
      ElMessage.success(
        `轮换完成：活动版本 v${result.active_version}，已轮换 ${result.rotated}，跳过 ${result.skipped}`
      )
      await loadProviders()
    } finally {
      rotating.value = false
    }
  }

  async function submit() {
    if (!(await formRef.value?.validate())) return
    saving.value = true
    try {
      const payload: ProviderInput = {
        ...form,
        capabilities: [...form.capabilities],
        config: { ...form.config, default: isDefault.value }
      }
      if (editingId.value && !payload.api_key) delete payload.api_key
      if (editingId.value) await updateProvider(editingId.value, payload)
      else await createProvider(payload)
      ElMessage.success('保存成功')
      dialogVisible.value = false
      await loadProviders()
    } finally {
      saving.value = false
    }
  }

  onMounted(loadProviders)
</script>
