<template>
  <AppShell>
    <div class="space-y-4">
      <div class="flex justify-between items-center">
        <h2 class="text-lg font-semibold">
          LLM Endpoints
        </h2>
        <NButton
          type="primary"
          @click="openCreate"
        >
          + 新增
        </NButton>
      </div>
      <NDataTable
        :data="endpoints"
        :columns="columns"
        :row-key="rowKey"
      />
      <NModal
        v-model:show="showForm"
        preset="card"
        title="LLM Endpoint"
        style="width: 520px"
      >
        <NForm>
          <NFormItem label="Provider">
            <NSelect
              v-model:value="form.provider"
              :options="providerOpts"
              :disabled="!!editing"
              @update:value="onProviderChange"
            />
          </NFormItem>
          <NFormItem label="显示名">
            <NInput v-model:value="form.display_name" />
          </NFormItem>
          <NFormItem label="Base URL">
            <NInput v-model:value="form.base_url" />
          </NFormItem>
          <NFormItem :label="editing ? 'API Key（留空则不修改）' : 'API Key'">
            <NInput
              v-model:value="form.api_key"
              type="password"
              show-password-on="click"
            />
          </NFormItem>
        </NForm>
        <template #footer>
          <div class="flex justify-end gap-2">
            <NButton @click="showForm = false">
              取消
            </NButton>
            <NButton
              type="primary"
              :loading="saving"
              :disabled="!canSave"
              @click="save"
            >
              保存
            </NButton>
          </div>
        </template>
      </NModal>
    </div>
  </AppShell>
</template>

<script setup lang="ts">
import { computed, h, onMounted, ref } from 'vue'
import {
  NButton,
  NDataTable,
  NForm,
  NFormItem,
  NInput,
  NModal,
  NSelect,
  useDialog,
  useMessage,
} from 'naive-ui'
import type { DataTableColumns } from 'naive-ui'

import AppShell from '@/layouts/AppShell.vue'
import {
  llmAdminApi,
  type LLMEndpoint,
  type LLMProvider,
} from '@/api/llmAdmin'

const endpoints = ref<LLMEndpoint[]>([])
const showForm = ref(false)
const editing = ref<LLMEndpoint | null>(null)
const form = ref<{
  provider: LLMProvider
  display_name: string
  base_url: string
  api_key: string
}>({
  provider: 'anthropic',
  display_name: '',
  base_url: '',
  api_key: '',
})
const saving = ref(false)
const msg = useMessage()
const dlg = useDialog()

const canSave = computed(() => {
  const f = form.value
  return (
    !!f.display_name.trim() &&
    !!f.base_url.trim() &&
    (!!editing.value || !!f.api_key.trim())
  )
})

const providerOpts: { label: string; value: LLMProvider }[] = [
  { label: 'Anthropic', value: 'anthropic' },
  { label: 'OpenAI / Compatible', value: 'openai' },
  { label: 'Gemini', value: 'gemini' },
]

const defaultBaseURL: Record<LLMProvider, string> = {
  anthropic: 'https://api.anthropic.com',
  openai: 'https://api.openai.com/v1',
  gemini: 'https://generativelanguage.googleapis.com/v1beta',
}

const columns: DataTableColumns<LLMEndpoint> = [
  { title: '显示名', key: 'display_name' },
  { title: 'Provider', key: 'provider' },
  { title: 'Base URL', key: 'base_url' },
  {
    title: '操作',
    key: 'actions',
    render: (row) =>
      h('div', { class: 'flex gap-1' }, [
        h(
          NButton,
          { size: 'small', onClick: () => testEndpoint(row.id) },
          { default: () => '测试' },
        ),
        h(
          NButton,
          { size: 'small', onClick: () => openEdit(row) },
          { default: () => '编辑' },
        ),
        h(
          NButton,
          { size: 'small', type: 'error', onClick: () => del(row) },
          { default: () => '删除' },
        ),
      ]),
  },
]

const rowKey = (row: LLMEndpoint) => row.id

onMounted(reload)

async function reload() {
  endpoints.value = await llmAdminApi.listEndpoints()
}

function openCreate() {
  editing.value = null
  form.value = {
    provider: 'anthropic',
    display_name: '',
    base_url: defaultBaseURL.anthropic,
    api_key: '',
  }
  showForm.value = true
}

function openEdit(ep: LLMEndpoint) {
  editing.value = ep
  form.value = {
    provider: ep.provider,
    display_name: ep.display_name,
    base_url: ep.base_url,
    api_key: '',
  }
  showForm.value = true
}

function onProviderChange(v: LLMProvider) {
  form.value.base_url = defaultBaseURL[v]
}

async function save() {
  saving.value = true
  try {
    if (editing.value) {
      await llmAdminApi.updateEndpoint(editing.value.id, {
        display_name: form.value.display_name,
        base_url: form.value.base_url,
        api_key: form.value.api_key || undefined,
      })
    } else {
      await llmAdminApi.createEndpoint({
        provider: form.value.provider,
        display_name: form.value.display_name,
        base_url: form.value.base_url,
        api_key: form.value.api_key,
      })
    }
    msg.success('已保存')
    showForm.value = false
    await reload()
  } catch (e) {
    msg.error(e instanceof Error ? e.message : String(e))
  } finally {
    saving.value = false
  }
}

async function testEndpoint(id: string) {
  try {
    await llmAdminApi.testEndpoint(id)
    msg.success('连通正常')
  } catch (e) {
    msg.error(e instanceof Error ? e.message : String(e))
  }
}

function del(ep: LLMEndpoint) {
  dlg.warning({
    title: `删除 ${ep.display_name}？`,
    positiveText: '删除',
    negativeText: '取消',
    onPositiveClick: async () => {
      await llmAdminApi.deleteEndpoint(ep.id)
      await reload()
    },
  })
}
</script>
