<template>
  <div class="page-content">
    <div class="mb-5 flex items-center justify-between gap-4">
      <div>
        <h2 class="text-xl font-semibold">API Key</h2>
        <p class="text-g-500 mt-1 text-sm">管理调用模型网关的应用凭据、权限范围与请求配额</p>
      </div>
      <ElButton type="primary" @click="dialogVisible = true">创建 API Key</ElButton>
    </div>

    <ElAlert class="mb-4" type="warning" :closable="false" title="密钥明文只在创建成功时显示一次；数据库仅保存 SHA-256 摘要。" />
    <ElTable v-loading="loading" :data="keys" row-key="id">
      <ElTableColumn prop="name" label="名称" min-width="180" />
      <ElTableColumn prop="key_prefix" label="前缀" min-width="180" />
      <ElTableColumn label="权限" min-width="180">
        <template #default="{ row }"><ElTag v-for="scope in row.scopes" :key="scope" class="mr-1">{{ scope }}</ElTag></template>
      </ElTableColumn>
      <ElTableColumn label="状态" width="100">
        <template #default="{ row }"><ElTag :type="row.enabled ? 'success' : 'info'">{{ row.enabled ? '启用' : '已撤销' }}</ElTag></template>
      </ElTableColumn>
      <ElTableColumn label="每分钟上限" min-width="130">
        <template #default="{ row }">{{ formatLimit(row.requests_per_minute) }}</template>
      </ElTableColumn>
      <ElTableColumn label="月请求配额" min-width="140">
        <template #default="{ row }">{{ formatLimit(row.monthly_request_quota) }}</template>
      </ElTableColumn>
      <ElTableColumn label="月 Token 配额" min-width="150">
        <template #default="{ row }">{{ formatLimit(row.monthly_token_quota) }}</template>
      </ElTableColumn>
      <ElTableColumn label="本月 Token 用量" min-width="160">
        <template #default="{ row }">
          <span>{{ (row.monthly_token_usage || 0).toLocaleString() }}</span>
          <span v-if="row.monthly_token_quota" class="text-g-500"> / {{ row.monthly_token_quota.toLocaleString() }}</span>
        </template>
      </ElTableColumn>
      <ElTableColumn label="最后使用" min-width="180">
        <template #default="{ row }">{{ formatTime(row.last_used_at) }}</template>
      </ElTableColumn>
      <ElTableColumn label="过期时间" min-width="180">
        <template #default="{ row }">{{ formatTime(row.expires_at) }}</template>
      </ElTableColumn>
      <ElTableColumn label="操作" width="140" fixed="right">
        <template #default="{ row }">
          <template v-if="row.enabled"><ElButton link type="primary" @click="openLimits(row)">配额</ElButton><ElButton link type="danger" @click="revoke(row)">撤销</ElButton></template>
        </template>
      </ElTableColumn>
    </ElTable>

    <ElDialog v-model="dialogVisible" title="创建 API Key" width="520px">
      <ElForm ref="formRef" :model="form" :rules="rules" label-width="90px">
        <ElFormItem label="名称" prop="name"><ElInput v-model="form.name" maxlength="128" /></ElFormItem>
        <ElFormItem label="权限"><ElCheckbox checked disabled>gateway:invoke</ElCheckbox></ElFormItem>
        <ElFormItem label="每分钟上限">
          <ElInputNumber v-model="form.requestsPerMinute" :min="0" :max="1000000" :step="10" class="w-full" />
          <div class="text-g-500 mt-1 text-xs">0 表示不限制；限制由 critical Redis 原子执行。</div>
        </ElFormItem>
        <ElFormItem label="月请求配额">
          <ElInputNumber v-model="form.monthlyRequestQuota" :min="0" :max="1000000000000" :step="1000" class="w-full" />
          <div class="text-g-500 mt-1 text-xs">0 表示不限制，按 UTC 自然月重置。</div>
        </ElFormItem>
        <ElFormItem label="月 Token 配额">
          <ElInputNumber v-model="form.monthlyTokenQuota" :min="0" :max="1000000000000000" :step="100000" class="w-full" />
          <div class="text-g-500 mt-1 text-xs">0 表示不限制；按上游 usage 的输入与输出 Token 合计。</div>
        </ElFormItem>
        <ElFormItem label="过期时间"><ElDatePicker v-model="expiresAt" type="datetime" placeholder="不设置则永不过期" class="w-full" /></ElFormItem>
      </ElForm>
      <template #footer><ElButton @click="dialogVisible = false">取消</ElButton><ElButton type="primary" :loading="saving" @click="create">创建</ElButton></template>
    </ElDialog>

    <ElDialog v-model="secretVisible" title="立即保存 API Key" width="620px" :close-on-click-modal="false">
      <ElAlert class="mb-4" type="warning" :closable="false" title="关闭后无法再次查看此密钥。" />
      <ElInput :model-value="createdSecret" readonly>
        <template #append><ElButton @click="copySecret">复制</ElButton></template>
      </ElInput>
      <template #footer><ElButton type="primary" @click="closeSecret">我已安全保存</ElButton></template>
    </ElDialog>

    <ElDialog v-model="limitsVisible" title="调整 API Key 配额" width="520px">
      <ElForm label-width="110px">
        <ElFormItem label="每分钟上限"><ElInputNumber v-model="limits.requestsPerMinute" :min="0" :max="1000000" :step="10" class="w-full" /></ElFormItem>
        <ElFormItem label="月请求配额"><ElInputNumber v-model="limits.monthlyRequestQuota" :min="0" :max="1000000000000" :step="1000" class="w-full" /></ElFormItem>
        <ElFormItem label="月 Token 配额"><ElInputNumber v-model="limits.monthlyTokenQuota" :min="0" :max="1000000000000000" :step="100000" class="w-full" /></ElFormItem>
        <div class="text-g-500 text-xs">0 表示不限制；调整后立即生效，已产生的当月用量不会清零。</div>
      </ElForm>
      <template #footer><ElButton @click="limitsVisible = false">取消</ElButton><ElButton type="primary" :loading="savingLimits" @click="saveLimits">保存</ElButton></template>
    </ElDialog>
  </div>
</template>

<script setup lang="ts">
  import { ElMessage, ElMessageBox, FormInstance, FormRules } from 'element-plus'
  import { APIKeyRecord, createAPIKey, fetchAPIKeys, revokeAPIKey, updateAPIKeyLimits } from '@/api/apiKeys'

  const keys = ref<APIKeyRecord[]>([])
  const loading = ref(false)
  const saving = ref(false)
  const dialogVisible = ref(false)
  const secretVisible = ref(false)
  const limitsVisible = ref(false)
  const savingLimits = ref(false)
  const editingID = ref('')
  const createdSecret = ref('')
  const expiresAt = ref<Date | null>(null)
  const formRef = ref<FormInstance>()
  const form = reactive({ name: '', requestsPerMinute: 60, monthlyRequestQuota: 0, monthlyTokenQuota: 0 })
  const limits = reactive({ requestsPerMinute: 0, monthlyRequestQuota: 0, monthlyTokenQuota: 0 })
  const rules: FormRules = { name: [{ required: true, message: '请输入名称', trigger: 'blur' }] }

  async function load() {
    loading.value = true
    try { keys.value = await fetchAPIKeys() } finally { loading.value = false }
  }

  async function create() {
    if (!(await formRef.value?.validate())) return
    saving.value = true
    try {
      const result = await createAPIKey({
        name: form.name,
        scopes: ['gateway:invoke'],
        requests_per_minute: form.requestsPerMinute,
        monthly_request_quota: form.monthlyRequestQuota,
        monthly_token_quota: form.monthlyTokenQuota,
        expires_at: expiresAt.value?.toISOString() || null
      })
      createdSecret.value = result.key || ''
      dialogVisible.value = false
      secretVisible.value = true
      form.name = ''
      form.requestsPerMinute = 60
      form.monthlyRequestQuota = 0
      form.monthlyTokenQuota = 0
      expiresAt.value = null
      await load()
    } finally { saving.value = false }
  }

  async function revoke(record: APIKeyRecord) {
    await ElMessageBox.confirm(`确认撤销 ${record.name}？撤销后立即失效且不可恢复。`, '撤销 API Key', { type: 'warning' })
    await revokeAPIKey(record.id)
    ElMessage.success('已撤销')
    await load()
  }

  function openLimits(record: APIKeyRecord) {
    editingID.value = record.id
    limits.requestsPerMinute = record.requests_per_minute
    limits.monthlyRequestQuota = record.monthly_request_quota
    limits.monthlyTokenQuota = record.monthly_token_quota
    limitsVisible.value = true
  }

  async function saveLimits() {
    savingLimits.value = true
    try {
      await updateAPIKeyLimits(editingID.value, {
        requests_per_minute: limits.requestsPerMinute,
        monthly_request_quota: limits.monthlyRequestQuota,
        monthly_token_quota: limits.monthlyTokenQuota
      })
      limitsVisible.value = false
      ElMessage.success('配额已立即生效')
      await load()
    } finally { savingLimits.value = false }
  }

  async function copySecret() {
    await navigator.clipboard.writeText(createdSecret.value)
    ElMessage.success('已复制')
  }

  function closeSecret() { createdSecret.value = ''; secretVisible.value = false }
  function formatTime(value: string | null) { return value ? new Date(value).toLocaleString() : '—' }
  function formatLimit(value: number) { return value > 0 ? value.toLocaleString() : '不限制' }
  onMounted(load)
</script>
