<template>
  <div class="page">
    <PageHeader
      :title="t('providers.title')"
      :description="t('providers.description')"
    >
      <template #actions>
        <el-button type="primary" :disabled="!currentCategorySupported" @click="openCreate">
          {{ t('providers.addProvider') }}
        </el-button>
      </template>
    </PageHeader>

    <AppCard>
      <div class="tabs-bar">
        <el-tabs v-model="activeCategory" @tab-change="load">
          <el-tab-pane v-for="cat in categories" :key="cat.key" :name="cat.key">
            <template #label>
              {{ cat.label }}
              <el-tag v-if="!cat.supported" size="small" type="info" class="soon-tag">{{ t('common.soon') }}</el-tag>
            </template>
          </el-tab-pane>
        </el-tabs>
      </div>

      <el-table :data="providers" v-loading="loading" row-key="id" size="small">
        <el-table-column type="expand">
          <template #default="{ row }">
            <div class="models-expand">
              <div v-if="!row.models?.length" class="models-empty">{{ t('providers.modelsEmpty') }}</div>
              <el-table v-else :data="row.models" size="small" class="models-table">
                <template v-if="row.category === 'image'">
                  <el-table-column :label="t('providers.ingressModelId')" min-width="180" show-overflow-tooltip>
                    <template #default="{ row: m }">{{ modelIngressId(m) }}</template>
                  </el-table-column>
                </template>
                <template v-else>
                  <el-table-column prop="model_id" :label="t('providers.upstreamModelId')" min-width="180" show-overflow-tooltip />
                  <el-table-column :label="t('providers.modelAlias')" min-width="140" show-overflow-tooltip>
                    <template #default="{ row: m }">{{ m.alias || '—' }}</template>
                  </el-table-column>
                </template>
                <el-table-column v-if="row.category === 'image'" prop="workflow_type" :label="t('providers.workflowType')" width="100" />
                <el-table-column prop="display_name" :label="t('providers.displayName')" min-width="160" show-overflow-tooltip />
                <el-table-column :label="t('common.enabled')" width="80">
                  <template #default="{ row: m }">
                    <el-switch
                      :model-value="m.enabled"
                      size="small"
                      @change="(v: boolean) => toggleModel(m, v, row)"
                    />
                  </template>
                </el-table-column>
                <el-table-column prop="created_at" :label="t('providers.syncedAt')" width="180">
                  <template #default="{ row: m }">{{ formatDateTime(m.created_at) }}</template>
                </el-table-column>
              </el-table>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="name" :label="t('common.name')" min-width="120" />
        <el-table-column prop="type" :label="t('providers.protocolType')" width="130">
          <template #default="{ row }">{{ protocolTypeLabel(row.type) }}</template>
        </el-table-column>
        <el-table-column :label="t('common.category')" width="100">
          <template #default="{ row }">{{ categoryLabel(row.category) }}</template>
        </el-table-column>
        <el-table-column :label="t('providers.models')" width="120">
          <template #default="{ row }">
            <el-tag size="small" :type="enabledModelCount(row) > 0 ? 'success' : 'info'">
              {{ enabledModelCount(row) }}/{{ row.models?.length || 0 }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="base_url" label="Base URL" show-overflow-tooltip min-width="160" />
        <el-table-column :label="t('providers.enabledEndpoints')" min-width="180">
          <template #default="{ row }">
            <el-tag v-for="ep in parseList(row.allowed_endpoints_json)" :key="ep" size="small" class="ep-tag">{{ ep }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="status" :label="t('common.status')" width="90">
          <template #default="{ row }">
            <el-tag :type="row.status === 'healthy' ? 'success' : 'info'" size="small">{{ row.status }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column :label="t('common.enabled')" width="80">
          <template #default="{ row }">
            <el-switch :model-value="row.enabled !== false" size="small" @change="(v: boolean) => toggleProvider(row, v)" />
          </template>
        </el-table-column>
        <el-table-column :label="t('common.actions')" width="320" fixed="right">
          <template #default="{ row }">
            <el-button size="small" link @click="openModels(row)">{{ t('providers.modelsAction') }}</el-button>
            <el-button size="small" link @click="openEndpoints(row)">{{ t('providers.endpointsAction') }}</el-button>
            <el-button size="small" link @click="openKeys(row)">{{ t('providers.keysAction') }}</el-button>
            <el-button v-if="row.category !== 'image' && providerHasListModels(row)" size="small" link @click="syncModels(row)">{{ t('providers.syncModels') }}</el-button>
            <el-button size="small" type="danger" link @click="remove(row)">{{ t('common.delete') }}</el-button>
          </template>
        </el-table-column>
      </el-table>
    </AppCard>

    <el-dialog v-model="showCreate" :title="t('providers.addDialogTitle')" width="640px" destroy-on-close>
      <el-form label-width="110px">
        <el-form-item :label="t('common.name')"><el-input v-model="form.name" /></el-form-item>
        <el-form-item :label="t('common.category')">
          <el-select v-model="form.category" @change="onCategoryChange">
            <el-option v-for="cat in categories" :key="cat.key" :label="cat.label" :value="cat.key" :disabled="!cat.supported" />
          </el-select>
        </el-form-item>
        <el-form-item :label="t('providers.protocolType')">
          <el-select v-model="form.type" @change="onProtocolTypeChange">
            <el-option
              v-for="pt in createProviderTypes"
              :key="pt.key"
              :label="pt.label"
              :value="pt.key"
            />
          </el-select>
        </el-form-item>
        <el-form-item :label="t('providers.baseUrl')"><el-input v-model="form.base_url" :placeholder="t('providers.baseUrlPlaceholder')" /></el-form-item>
        <template v-if="form.category !== 'image'">
          <el-divider>{{ t('providers.endpointDivider') }}</el-divider>
          <div v-for="ep in createEndpointMeta" :key="ep.key" class="endpoint-row">
            <el-checkbox v-model="form.allowedMap[ep.key]">{{ ep.label }}</el-checkbox>
            <el-input v-model="form.pathMap[ep.key]" :placeholder="ep.default_path" size="small" />
          </div>
        </template>
      </el-form>
      <template #footer>
        <el-button @click="showCreate = false">{{ t('common.cancel') }}</el-button>
        <el-button type="primary" @click="create">{{ t('common.create') }}</el-button>
      </template>
    </el-dialog>

    <el-drawer v-model="endpointVisible" :title="t('providers.endpointConfigTitle', { name: current?.name || '' })" size="50%">
      <el-form label-width="110px">
        <el-form-item :label="t('providers.baseUrl')"><el-input v-model="editForm.base_url" /></el-form-item>
        <template v-if="current?.category !== 'image'">
          <el-divider>{{ t('providers.endpointEditDivider') }}</el-divider>
          <p class="form-hint">{{ t('providers.pathHint') }}</p>
          <div v-for="ep in editEndpointMeta" :key="ep.key" class="endpoint-row">
            <el-checkbox v-model="editForm.allowedMap[ep.key]">{{ ep.label }}</el-checkbox>
            <el-input v-model="editForm.pathMap[ep.key]" :placeholder="ep.default_path" size="small" />
          </div>
        </template>
      </el-form>
      <template #footer>
        <el-button type="primary" @click="saveEndpoints">{{ t('common.save') }}</el-button>
      </template>
    </el-drawer>

    <el-drawer v-model="keysVisible" :title="t('providers.keysTitle', { name: current?.name || '' })" size="50%">
      <div class="drawer-toolbar">
        <el-button type="primary" size="small" @click="showKeyForm = true">{{ t('providers.addKey') }}</el-button>
      </div>
      <el-table :data="keys" size="small">
        <el-table-column prop="name" :label="t('common.name')" />
        <el-table-column prop="weight" :label="t('common.weight')" width="80" />
        <el-table-column prop="enabled" :label="t('common.enabled')" width="80">
          <template #default="{ row }"><el-tag :type="row.enabled ? 'success' : 'info'" size="small">{{ row.enabled ? t('common.yes') : t('common.no') }}</el-tag></template>
        </el-table-column>
        <el-table-column prop="requests_today" :label="t('providers.requestsToday')" />
        <el-table-column :label="t('common.actions')" width="100">
          <template #default="{ row }">
            <el-button size="small" type="danger" link @click="deleteKey(row)">{{ t('common.delete') }}</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-drawer>

    <el-dialog v-model="showKeyForm" :title="t('providers.addKeyDialogTitle')" width="480px" destroy-on-close>
      <el-form label-width="120px">
        <el-form-item :label="t('common.name')"><el-input v-model="keyForm.name" /></el-form-item>
        <el-form-item :label="t('providers.apiKey')"><el-input v-model="keyForm.api_key" type="password" show-password /></el-form-item>
        <el-form-item :label="t('common.weight')"><el-input-number v-model="keyForm.weight" :min="0.1" :step="0.1" /></el-form-item>
        <el-form-item :label="t('providers.modelWhitelist')"><el-input v-model="keyForm.models" :placeholder="t('providers.modelWhitelistPlaceholder')" /></el-form-item>
        <el-form-item :label="t('providers.maxRequestsPerDay')"><el-input-number v-model="keyForm.max_requests_per_day" :min="0" /></el-form-item>
        <el-form-item :label="t('providers.maxTokensPerDay')"><el-input-number v-model="keyForm.max_tokens_per_day" :min="0" /></el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showKeyForm = false">{{ t('common.cancel') }}</el-button>
        <el-button type="primary" @click="createKey">{{ t('common.add') }}</el-button>
      </template>
    </el-dialog>

    <el-drawer v-model="modelsVisible" :title="t('providers.modelsTitle', { name: current?.name || '' })" size="50%">
      <div class="drawer-toolbar">
        <el-button v-if="current?.category === 'image'" type="primary" size="small" @click="showWorkflowDialog = true">
          {{ t('providers.addWorkflowModel') }}
        </el-button>
        <template v-else-if="current">
          <el-button v-if="providerHasListModels(current)" type="primary" size="small" @click="syncModels(current)">
            {{ t('providers.syncModels') }}
          </el-button>
          <el-button type="primary" size="small" plain @click="openAddModel">{{ t('providers.addModel') }}</el-button>
        </template>
        <span class="form-hint u-mt-0">
          {{ t('providers.modelsSummary', { total: providerModels.length, enabled: enabledProviderModelCount }) }}
        </span>
      </div>
      <el-table :data="providerModels" size="small" v-loading="modelsLoading">
        <template v-if="current?.category === 'image'">
          <el-table-column :label="t('providers.ingressModelId')" min-width="180" show-overflow-tooltip>
            <template #default="{ row }">{{ modelIngressId(row) }}</template>
          </el-table-column>
        </template>
        <template v-else>
          <el-table-column prop="model_id" :label="t('providers.upstreamModelId')" min-width="180" show-overflow-tooltip />
          <el-table-column :label="t('providers.modelAlias')" min-width="140" show-overflow-tooltip>
            <template #default="{ row }">{{ row.alias || '—' }}</template>
          </el-table-column>
        </template>
        <el-table-column v-if="current?.category === 'image'" prop="workflow_type" :label="t('providers.workflowType')" width="100" />
        <el-table-column prop="display_name" :label="t('providers.displayName')" min-width="160" show-overflow-tooltip />
        <el-table-column :label="t('common.enabled')" width="80">
          <template #default="{ row }">
            <el-switch
              :model-value="row.enabled"
              size="small"
              @change="(v: boolean) => toggleModel(row, v)"
            />
          </template>
        </el-table-column>
        <el-table-column prop="created_at" :label="t('providers.syncedAt')" width="180">
          <template #default="{ row }">{{ formatDateTime(row.created_at) }}</template>
        </el-table-column>
        <el-table-column :label="t('common.actions')" width="120">
          <template #default="{ row }">
            <el-button size="small" link @click="openEditModel(row)">{{ t('common.edit') }}</el-button>
            <el-button size="small" type="danger" link @click="deleteModel(row)">{{ t('common.delete') }}</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-drawer>

    <el-dialog v-model="showAddModel" :title="t('providers.addModelDialogTitle')" width="480px" destroy-on-close>
      <el-form label-width="100px">
        <el-form-item :label="t('providers.modelId')" required>
          <el-input v-model="addModelForm.model_id" placeholder="text-embedding-3-small" />
        </el-form-item>
        <el-form-item :label="t('providers.modelAlias')">
          <el-input v-model="addModelForm.alias" :placeholder="t('providers.modelAliasPlaceholder')" />
          <p class="form-hint">{{ t('providers.modelAliasHint') }}</p>
        </el-form-item>
        <el-form-item :label="t('providers.displayName')">
          <el-input v-model="addModelForm.display_name" :placeholder="t('providers.modelId')" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showAddModel = false">{{ t('common.cancel') }}</el-button>
        <el-button type="primary" @click="createModel">{{ t('common.create') }}</el-button>
      </template>
    </el-dialog>

    <el-dialog v-model="showEditModel" :title="t('providers.editModelDialogTitle')" width="480px" destroy-on-close>
      <el-form label-width="110px">
        <template v-if="current?.category === 'image'">
          <el-form-item :label="t('providers.ingressModelId')" required>
            <el-input v-model="editModelForm.model_id" placeholder="luminary/flux-sdxl" />
            <p class="form-hint">{{ t('providers.ingressModelIdHint') }}</p>
          </el-form-item>
        </template>
        <template v-else>
          <el-form-item :label="t('providers.upstreamModelId')">
            <el-input v-model="editModelForm.model_id" />
          </el-form-item>
          <el-form-item :label="t('providers.modelAlias')">
            <el-input v-model="editModelForm.alias" :placeholder="t('providers.modelAliasPlaceholder')" />
            <p class="form-hint">{{ t('providers.modelAliasHint') }}</p>
          </el-form-item>
        </template>
        <el-form-item :label="t('providers.displayName')">
          <el-input v-model="editModelForm.display_name" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showEditModel = false">{{ t('common.cancel') }}</el-button>
        <el-button type="primary" @click="saveEditModel">{{ t('common.save') }}</el-button>
      </template>
    </el-dialog>

    <WorkflowModelDialog
      v-if="current"
      v-model="showWorkflowDialog"
      :provider-id="current.id"
      @saved="current && openModels(current)"
    />
  </div>
</template>

<script setup lang="ts">
import { computed, nextTick, onMounted, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { ElMessage, ElMessageBox } from 'element-plus'
import api, { type Provider, type ProviderKey, type ModelEntry } from '@/api/client'
import PageHeader from '@/components/PageHeader.vue'
import AppCard from '@/components/AppCard.vue'
import WorkflowModelDialog from '@/components/WorkflowModelDialog.vue'
import { formatDateTime } from '@/utils/format'

const { t } = useI18n()

interface CategoryMeta { key: string; label: string; supported: boolean }
interface ProviderTypeMeta { key: string; label: string }
interface EndpointMetaItem { key: string; label: string; method: string; ingress_path: string; default_path: string }

const categories = ref<CategoryMeta[]>([])
const createProviderTypes = ref<ProviderTypeMeta[]>([])
const createEndpointMeta = ref<EndpointMetaItem[]>([])
const editEndpointMeta = ref<EndpointMetaItem[]>([])
const providerTypeLabels = ref<Record<string, string>>({})
const activeCategory = ref('llm')
const providers = ref<Provider[]>([])
const loading = ref(false)
const showCreate = ref(false)
const form = ref({
  name: '', type: 'openai', category: 'llm', base_url: '',
  allowedMap: {} as Record<string, boolean>,
  pathMap: {} as Record<string, string>,
})
const editForm = ref({
  base_url: '',
  allowedMap: {} as Record<string, boolean>,
  pathMap: {} as Record<string, string>,
})
const endpointVisible = ref(false)
const current = ref<Provider | null>(null)
const keysVisible = ref(false)
const keys = ref<ProviderKey[]>([])
const showKeyForm = ref(false)
const modelsVisible = ref(false)
const modelsLoading = ref(false)
const providerModels = ref<ModelEntry[]>([])

const enabledProviderModelCount = computed(() =>
  providerModels.value.filter(m => m.enabled).length,
)
const showWorkflowDialog = ref(false)
const showAddModel = ref(false)
const showEditModel = ref(false)
const addModelForm = ref({ model_id: '', alias: '', display_name: '' })
const editModelForm = ref({ id: 0, model_id: '', alias: '', display_name: '' })
const keyForm = ref({ name: '', api_key: '', weight: 1, models: '["*"]', max_requests_per_day: 0, max_tokens_per_day: 0 })

let createMetaSeq = 0
let editMetaSeq = 0

const currentCategorySupported = computed(() =>
  categories.value.find(c => c.key === activeCategory.value)?.supported ?? true,
)

function categoryLabel(key: string) {
  return categories.value.find(c => c.key === key)?.label || key
}

function protocolTypeLabel(key: string) {
  return providerTypeLabels.value[key] || key
}

function defaultProviderType(category: string, types: ProviderTypeMeta[]) {
  if (types.length > 0) return types[0].key
  return category === 'image' ? 'comfyui' : 'openai'
}

function apiErrorMessage(error: string | undefined, fallback: string) {
  if (error === 'provider name already exists') return t('providers.providerNameExists')
  if (error === 'model alias already exists') return t('providers.modelAliasExists')
  return error || fallback
}

function providerHasListModels(row: Provider) {
  return parseList(row.allowed_endpoints_json).includes('list_models')
}

async function fetchEndpointMeta(category: string, type?: string) {
  const res = await api.get('/endpoint-meta', { params: { category, type: type || undefined } })
  return {
    categories: (res.data.categories || []) as CategoryMeta[],
    providerTypes: (res.data.provider_types || []) as ProviderTypeMeta[],
    allProviderTypes: (res.data.all_provider_types || []) as ProviderTypeMeta[],
    endpoints: (res.data.endpoints || []) as EndpointMetaItem[],
  }
}

function applyDefaultEndpoints(
  category: string,
  endpoints: EndpointMetaItem[],
  allowedMap: Record<string, boolean>,
  pathMap: Record<string, string>,
  reset: boolean,
) {
  const defaultKeys = defaultEndpointsForCategory(category)
  for (const ep of endpoints) {
    if (reset || allowedMap[ep.key] === undefined) {
      allowedMap[ep.key] = defaultKeys.includes(ep.key)
    }
    if (reset || pathMap[ep.key] === undefined) {
      pathMap[ep.key] = pathMap[ep.key] || ''
    }
  }
}

async function loadCreateEndpointMeta(category: string, type: string, reset = false) {
  const seq = ++createMetaSeq
  const data = await fetchEndpointMeta(category, type)
  if (seq !== createMetaSeq) return data
  if (!categories.value.length) categories.value = data.categories
  createProviderTypes.value = data.providerTypes
  for (const pt of data.providerTypes) providerTypeLabels.value[pt.key] = pt.label
  createEndpointMeta.value = data.endpoints
  applyDefaultEndpoints(category, data.endpoints, form.value.allowedMap, form.value.pathMap, reset)
  return data
}

async function loadEditEndpointMeta(category: string, type: string) {
  const seq = ++editMetaSeq
  const data = await fetchEndpointMeta(category, type)
  if (seq !== editMetaSeq) return data
  editEndpointMeta.value = data.endpoints
  return data
}

function parseList(json: string) {
  try { return JSON.parse(json || '[]') } catch { return [] }
}

function parsePaths(json: string): Record<string, string> {
  try { return JSON.parse(json || '{}') } catch { return {} }
}

function enabledModelCount(row: Provider) {
  return (row.models ?? []).filter(m => m.enabled).length
}

function syncModelState(m: ModelEntry, enabled: boolean, providerRow?: Provider) {
  m.enabled = enabled
  if (providerRow?.models) {
    const item = providerRow.models.find(x => x.id === m.id)
    if (item) item.enabled = enabled
  }
  if (current.value?.id === m.provider_id) {
    const item = providerModels.value.find(x => x.id === m.id)
    if (item) item.enabled = enabled
  }
  const provider = providers.value.find(p => p.id === m.provider_id)
  if (provider?.models) {
    const item = provider.models.find(x => x.id === m.id)
    if (item) item.enabled = enabled
  }
}

async function toggleModel(m: ModelEntry, enabled: boolean, providerRow?: Provider) {
  if (!m.id || !m.provider_id) {
    ElMessage.warning(t('providers.modelNotLoaded'))
    return
  }
  const prev = m.enabled
  syncModelState(m, enabled, providerRow)
  try {
    await api.put(`/providers/${m.provider_id}/models/${m.id}`, { enabled, model_id: m.model_id })
    ElMessage.success(enabled ? t('providers.modelEnabled') : t('providers.modelDisabled'))
  } catch (e: any) {
    syncModelState(m, prev, providerRow)
    const msg = e.response?.data?.error
    ElMessage.error(msg === 'not found' || msg === 'model not found' ? t('providers.modelNotFound') : (msg || t('providers.updateFailed')))
  }
}

async function onProtocolTypeChange() {
  await nextTick()
  const allowedMap = { ...form.value.allowedMap }
  const pathMap = { ...form.value.pathMap }
  await loadCreateEndpointMeta(form.value.category, form.value.type)
  for (const ep of createEndpointMeta.value) {
    if (allowedMap[ep.key] !== undefined) form.value.allowedMap[ep.key] = allowedMap[ep.key]
    if (pathMap[ep.key] !== undefined) form.value.pathMap[ep.key] = pathMap[ep.key]
  }
}

function defaultEndpointsForCategory(category: string) {
  switch (category) {
    case 'embedding':
      return ['list_models', 'embeddings']
    case 'rerank':
      return ['list_models', 'rerank']
    case 'image':
      return []
    default:
      return ['list_models', 'chat_completion']
  }
}

function onCategoryChange() {
  void (async () => {
    form.value.allowedMap = {}
    form.value.pathMap = {}
    const meta = await fetchEndpointMeta(form.value.category)
    form.value.type = defaultProviderType(form.value.category, meta.providerTypes)
    await loadCreateEndpointMeta(form.value.category, form.value.type, true)
  })()
}

async function toggleProvider(row: Provider, enabled: boolean) {
  await api.put(`/providers/${row.id}`, { enabled })
  row.enabled = enabled
  ElMessage.success(enabled ? t('providers.providerEnabled') : t('providers.providerDisabled'))
}

function buildPayload(baseURL: string, allowedMap: Record<string, boolean>, pathMap: Record<string, string>) {
  const allowed_endpoints = Object.keys(allowedMap).filter(k => allowedMap[k])
  const endpoint_paths: Record<string, string> = {}
  for (const [k, v] of Object.entries(pathMap)) {
    if (v.trim()) endpoint_paths[k] = v.trim()
  }
  return { base_url: baseURL, allowed_endpoints, endpoint_paths }
}

async function load() {
  loading.value = true
  try {
    const res = await api.get('/providers', { params: { category: activeCategory.value } })
    providers.value = (res.data.data ?? []).map((p: Provider) => ({
      ...p,
      models: p.models ?? [],
    }))
  } finally {
    loading.value = false
  }
}

async function openCreate() {
  form.value = {
    name: '',
    type: 'openai',
    category: activeCategory.value,
    base_url: '',
    allowedMap: {},
    pathMap: {},
  }
  const meta = await fetchEndpointMeta(activeCategory.value)
  if (!categories.value.length) categories.value = meta.categories
  for (const pt of meta.providerTypes) providerTypeLabels.value[pt.key] = pt.label
  form.value.type = defaultProviderType(activeCategory.value, meta.providerTypes)
  await loadCreateEndpointMeta(activeCategory.value, form.value.type, true)
  showCreate.value = true
}

async function create() {
  const payload = {
    name: form.value.name,
    type: form.value.type,
    category: form.value.category,
    ...buildPayload(form.value.base_url, form.value.allowedMap, form.value.pathMap),
  }
  try {
    await api.post('/providers', payload)
  } catch (e: any) {
    ElMessage.error(apiErrorMessage(e.response?.data?.error, t('providers.updateFailed')))
    return
  }
  showCreate.value = false
  ElMessage.success(t('providers.createSuccess'))
  load()
}

async function openEndpoints(row: Provider) {
  current.value = row
  await loadEditEndpointMeta(row.category || 'llm', row.type)
  const allowed = parseList(row.allowed_endpoints_json)
  const paths = parsePaths(row.endpoint_paths_json)
  const allowedMap: Record<string, boolean> = {}
  const pathMap: Record<string, string> = {}
  for (const ep of editEndpointMeta.value) {
    allowedMap[ep.key] = allowed.includes(ep.key)
    pathMap[ep.key] = paths[ep.key] || ''
  }
  editForm.value = { base_url: row.base_url, allowedMap, pathMap }
  endpointVisible.value = true
}

async function saveEndpoints() {
  if (!current.value) return
  await api.put(`/providers/${current.value.id}`, buildPayload(
    editForm.value.base_url,
    editForm.value.allowedMap,
    editForm.value.pathMap,
  ))
  endpointVisible.value = false
  ElMessage.success(t('providers.saved'))
  load()
}

async function remove(row: Provider) {
  await ElMessageBox.confirm(t('common.confirmDelete'))
  await api.delete(`/providers/${row.id}`)
  ElMessage.success(t('providers.deleted'))
  load()
}

async function openKeys(row: Provider) {
  current.value = row
  const res = await api.get(`/providers/${row.id}/keys`)
  keys.value = res.data.data
  keysVisible.value = true
}

async function openModels(row: Provider) {
  current.value = row
  modelsVisible.value = true
  modelsLoading.value = true
  providerModels.value = []
  try {
    const res = await api.get(`/providers/${row.id}/models`)
    const models = res.data.data ?? []
    providerModels.value = models
    row.models = models
  } finally {
    modelsLoading.value = false
  }
}

async function syncModels(row: Provider) {
  try {
    const res = await api.post(`/providers/${row.id}/sync-models`)
    ElMessage.success(t('providers.syncedCount', { count: res.data.synced }))
    await load()
    const updated = providers.value.find(p => p.id === row.id)
    if (updated) {
      Object.assign(row, updated)
      if (current.value?.id === row.id) {
        current.value = updated
      }
    }
    if (modelsVisible.value && current.value?.id === row.id) {
      await openModels(row)
    }
  } catch (e: any) {
    ElMessage.error(e.response?.data?.error || t('providers.syncFailed'))
  }
}

async function createKey() {
  if (!current.value) return
  let models: string[] = ['*']
  try { models = JSON.parse(keyForm.value.models) } catch { /* keep */ }
  await api.post(`/providers/${current.value.id}/keys`, { ...keyForm.value, models })
  showKeyForm.value = false
  keyForm.value = { name: '', api_key: '', weight: 1, models: '["*"]', max_requests_per_day: 0, max_tokens_per_day: 0 }
  openKeys(current.value)
  ElMessage.success(t('providers.keyAdded'))
}

async function deleteKey(row: ProviderKey) {
  await api.delete(`/provider-keys/${row.id}`)
  if (current.value) openKeys(current.value)
}

function openAddModel() {
  addModelForm.value = { model_id: '', alias: '', display_name: '' }
  showAddModel.value = true
}

function modelIngressId(m: ModelEntry) {
  return m.alias || m.model_id
}

function openEditModel(m: ModelEntry) {
  const isImage = current.value?.category === 'image'
  editModelForm.value = {
    id: m.id,
    model_id: isImage ? modelIngressId(m) : m.model_id,
    alias: isImage ? '' : (m.alias || ''),
    display_name: m.display_name || '',
  }
  showEditModel.value = true
}

async function saveEditModel() {
  if (!current.value || !editModelForm.value.id) return
  const isImage = current.value.category === 'image'
  try {
    await api.put(`/providers/${current.value.id}/models/${editModelForm.value.id}`, {
      model_id: editModelForm.value.model_id.trim(),
      ...(isImage ? { alias: '' } : { alias: editModelForm.value.alias.trim() }),
      display_name: editModelForm.value.display_name.trim(),
    })
  } catch (e: any) {
    ElMessage.error(apiErrorMessage(e.response?.data?.error, t('providers.updateFailed')))
    return
  }
  showEditModel.value = false
  ElMessage.success(t('providers.saved'))
  await openModels(current.value)
  await load()
}

async function createModel() {
  if (!current.value) return
  const modelId = addModelForm.value.model_id.trim()
  if (!modelId) {
    ElMessage.warning(t('providers.modelIdRequired'))
    return
  }
  const displayName = addModelForm.value.display_name.trim() || modelId
  try {
    await api.post(`/providers/${current.value.id}/models`, {
      model_id: modelId,
      alias: addModelForm.value.alias.trim(),
      display_name: displayName,
    })
  } catch (e: any) {
    ElMessage.error(apiErrorMessage(e.response?.data?.error, t('providers.updateFailed')))
    return
  }
  showAddModel.value = false
  ElMessage.success(t('providers.modelAdded'))
  await openModels(current.value)
  await load()
}

async function deleteModel(m: ModelEntry) {
  if (!current.value || !m.id) return
  await ElMessageBox.confirm(t('providers.confirmDeleteModel'))
  try {
    await api.delete(`/providers/${current.value.id}/models/${m.id}`)
  } catch (e: any) {
    ElMessage.error(e.response?.data?.error || t('providers.updateFailed'))
    return
  }
  ElMessage.success(t('providers.modelDeleted'))
  await openModels(current.value)
  await load()
}

onMounted(async () => {
  const meta = await fetchEndpointMeta('llm')
  categories.value = meta.categories
  for (const pt of (meta.allProviderTypes?.length ? meta.allProviderTypes : meta.providerTypes) ?? []) {
    providerTypeLabels.value[pt.key] = pt.label
  }
  load()
})
</script>
