<template>
  <div class="page-wrap">
    <div class="breadcrumb">
      <span>模型管理</span>
      <span>/</span>
      <span>AI 模型配置</span>
    </div>

    <div class="panel-card">
      <div class="panel-head">
        <div class="panel-title">可用模型列表</div>
        <a-button @click="openAdd">添加模型</a-button>
      </div>
      <div class="panel-body">
        <div class="model-card" v-for="item in models" :key="item.id">
          <div class="mc-icon">{{ item.name?.slice(0, 1)?.toUpperCase() || 'M' }}</div>
          <div class="mc-info">
            <div class="mc-name">{{ item.name }}</div>
            <div class="mc-provider">{{ item.provider }} · {{ item.api_endpoint }}</div>
            <div class="mc-provider">密钥：{{ item.api_key_preview || '未设置' }}</div>
            <div class="mc-provider">流式传输：{{ item.supports_streaming ? '支持' : '关闭' }}</div>
            <div class="mc-provider">思考模式：{{ item.enable_reasoning ? '开启' : '关闭' }}</div>
            <div v-if="isDeepSeek(item) && balanceMap[item.id]" class="mc-provider">
              余额：{{ formatBalanceText(balanceMap[item.id]) }}
            </div>
          </div>
          <div :class="['mc-status', item.status === 'enabled' ? 'on' : 'off']">
            {{ item.status === 'enabled' ? '已启用' : '已禁用' }}
          </div>
          <div class="mc-actions">
            <a-button size="small" :loading="testingMap[item.id]" @click="runTest(item)">
              <template #icon><reload-outlined /></template>
              刷新测试
            </a-button>
            <a-button v-if="isDeepSeek(item)" size="small" :loading="balanceLoadingMap[item.id]" @click="fetchBalance(item)">
              查看余额
            </a-button>
            <a-button size="small" @click="openEdit(item)">编辑</a-button>
            <a-button size="small" @click="toggleStatus(item)">{{ item.status === 'enabled' ? '禁用' : '启用' }}</a-button>
          </div>
        </div>
      </div>
    </div>

    <a-modal v-model:open="modalOpen" :title="isEdit ? '编辑模型' : '添加模型'" @ok="saveModel">
      <a-form layout="vertical">
        <a-form-item label="模型名称">
          <a-input v-model:value="form.name" />
        </a-form-item>
        <a-form-item label="供应厂商">
          <a-select v-model:value="providerPreset" @change="applyProviderPreset">
            <a-select-option value="deepseek">DeepSeek</a-select-option>
            <a-select-option value="custom">自定义</a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item v-if="providerPreset === 'custom'" label="自定义厂商名称">
          <a-input v-model:value="form.provider" placeholder="例如 OpenAI / Anthropic / 其他" />
        </a-form-item>
        <a-form-item label="API 格式">
          <a-select v-model:value="form.api_format">
            <a-select-option value="openai">OpenAI 格式</a-select-option>
            <a-select-option value="anthropic">Anthropic 格式</a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item label="API 地址">
          <a-input v-model:value="form.api_endpoint" />
        </a-form-item>
        <a-form-item label="支持流式传输">
          <a-switch v-model:checked="form.supports_streaming" />
        </a-form-item>
        <a-form-item label="开启思考模式">
          <a-switch v-model:checked="form.enable_reasoning" />
        </a-form-item>
        <a-form-item label="API Key">
          <a-input-password v-model:value="form.api_key" />
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { message } from 'ant-design-vue'
import { ReloadOutlined } from '@ant-design/icons-vue'
import { useModelStore } from '@/stores/model'

const store = useModelStore()
const models = ref<any[]>([])
const modalOpen = ref(false)
const isEdit = ref(false)
const editId = ref(0)
const form = ref({ name: '', provider: '', api_format: 'openai', api_endpoint: '', api_key: '', supports_streaming: false, enable_reasoning: false })
const providerPreset = ref<'deepseek' | 'custom'>('custom')
const testingMap = ref<Record<number, boolean>>({})
const balanceLoadingMap = ref<Record<number, boolean>>({})
const balanceMap = ref<Record<number, { is_available: boolean; balance_infos: Array<{ currency: string; total_balance: string; granted_balance: string; topped_up_balance: string }> }>>({})

function isDeepSeek(item: any) {
  const provider = (item?.provider || '').trim().toLowerCase()
  return provider === 'deepseek'
}

function applyProviderPreset(value: 'deepseek' | 'custom') {
  if (value === 'deepseek') {
    form.value.provider = 'DeepSeek'
    form.value.api_format = 'openai'
    if (!form.value.api_endpoint || form.value.api_endpoint.includes('deepseek')) {
      form.value.api_endpoint = 'https://api.deepseek.com'
    }
    return
  }
  if (form.value.provider === 'DeepSeek') {
    form.value.provider = ''
  }
}

function inferProviderPreset(item?: any) {
  providerPreset.value = isDeepSeek(item || form.value) ? 'deepseek' : 'custom'
}

function formatBalanceText(data: { is_available: boolean; balance_infos: Array<{ currency: string; total_balance: string; granted_balance: string; topped_up_balance: string }> }) {
  const infos = data?.balance_infos || []
  if (!infos.length) return data?.is_available ? '可用' : '不可用'
  return infos
    .map((item) => `${item.currency} ${item.total_balance}（充值 ${item.topped_up_balance} / 赠送 ${item.granted_balance}）`)
    .join('；')
}

async function refreshList() {
  await store.fetchList()
  models.value = store.models as any
}

onMounted(async () => {
  await refreshList()
})

function openAdd() {
  isEdit.value = false
  form.value = { name: '', provider: '', api_format: 'openai', api_endpoint: '', api_key: '', supports_streaming: false, enable_reasoning: false }
  providerPreset.value = 'deepseek'
  applyProviderPreset('deepseek')
  modalOpen.value = true
}

function openEdit(item: any) {
  isEdit.value = true
  editId.value = item.id
  form.value = {
    name: item.name,
    provider: item.provider,
    api_format: item.api_format,
    api_endpoint: item.api_endpoint,
    api_key: '',
    supports_streaming: !!item.supports_streaming,
    enable_reasoning: !!item.enable_reasoning,
  }
  inferProviderPreset(item)
  modalOpen.value = true
}

async function saveModel() {
  if (isEdit.value) {
    await store.update(editId.value, form.value)
  } else {
    await store.create(form.value)
  }
  modalOpen.value = false
  await refreshList()
  message.success('保存成功')
}

async function toggleStatus(item: any) {
  await store.update(item.id, { status: item.status === 'enabled' ? 'disabled' : 'enabled' })
  await refreshList()
  message.success('状态已更新')
}

async function runTest(item: any) {
  testingMap.value[item.id] = true
  try {
    const result: any = await store.test(item.id)
    message.success(result.data?.message || `模型 ${item.name} 测试成功`, 2)
  } catch (error: any) {
    message.error(error.message || '连接测试失败', 2)
  } finally {
    testingMap.value[item.id] = false
  }
}

async function fetchBalance(item: any) {
  balanceLoadingMap.value[item.id] = true
  try {
    const result: any = await store.balance(item.id)
    balanceMap.value[item.id] = result.data
    message.success(`已刷新 ${item.name} 余额`, 2)
  } catch (error: any) {
    message.error(error.message || '余额查询失败', 2)
  } finally {
    balanceLoadingMap.value[item.id] = false
  }
}
</script>

<style scoped>
.page-wrap {
  padding: 24px 32px 32px;
}

.breadcrumb {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: #9aa1ad;
  margin-bottom: 16px;
}

.panel-card {
  background: #fff;
  border-radius: 12px;
  border: 1px solid #e0e2e6;
  overflow: hidden;
}

.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 24px;
  border-bottom: 1px solid #eaecef;
}

.panel-title {
  font-size: 15px;
  font-weight: 600;
}

.panel-body {
  padding: 24px;
}

.model-card {
  border: 1px solid #eaecef;
  border-radius: 8px;
  padding: 16px;
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  gap: 16px;
}

.mc-icon {
  width: 40px;
  height: 40px;
  border-radius: 8px;
  background: #eeeefb;
  color: #5b5bd6;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  flex-shrink: 0;
}

.mc-info {
  flex: 1;
  min-width: 0;
}

.mc-name {
  font-size: 14px;
  font-weight: 500;
}

.mc-provider {
  font-size: 12px;
  color: #9aa1ad;
}

.mc-status {
  font-size: 12px;
  white-space: nowrap;
}

.mc-status.on {
  color: #1a8c4a;
}

.mc-status.off {
  color: #9aa1ad;
}

.mc-actions {
  display: flex;
  gap: 8px;
}
</style>
