<template>
	<div class="management-page">
		<div class="page-head">
			<div>
				<h1>{{ t('pages.model.title') }}</h1>
				<p>{{ t('pages.model.subtitle') }}</p>
			</div>
		</div>

		<div class="model-manage">
			<el-card class="list-card">
				<div class="action-bar mb-12px">
					<div class="action-bar__left">
						<el-input
							v-model="searchForm.keyword"
							clearable
							:placeholder="t('pages.model.searchPlaceholder')"
							class="search-input"
							@keyup.enter="handleSearch"
						>
							<template #prefix>
								<el-icon><Search /></el-icon>
							</template>
						</el-input>
						<el-select
							v-model="searchForm.type"
							clearable
							:placeholder="t('pages.model.typePlaceholder')"
							style="width: 160px"
							@change="handleSearch"
						>
							<el-option :label="t('pages.model.types.KnowledgeQA')" value="KnowledgeQA" />
							<el-option :label="t('pages.model.types.Embedding')" value="Embedding" />
							<el-option :label="t('pages.model.types.Rerank')" value="Rerank" />
							<el-option :label="t('pages.model.types.VLLM')" value="VLLM" />
						</el-select>
						<el-select
							v-model="searchForm.source"
							clearable
							:placeholder="t('pages.model.sourcePlaceholder')"
							style="width: 140px"
							@change="handleSearch"
						>
							<el-option :label="t('pages.model.sources.local')" value="local" />
							<el-option :label="t('pages.model.sources.remote')" value="remote" />
						</el-select>
						<div class="toolbar-actions">
							<el-button type="primary" @click="handleSearch">
								<el-icon><Search /></el-icon>
								{{ t('common.search') }}
							</el-button>
							<el-button @click="handleResetSearch">
								<el-icon><RefreshRight /></el-icon>
								{{ t('common.reset') }}
							</el-button>
						</div>
					</div>
					<div class="action-bar__right">
						<el-button v-permission="'add'" type="primary" @click="openCreateModel">
							<el-icon><Plus /></el-icon>
							{{ t('pages.model.create') }}
						</el-button>
						<el-button @click="getAllModelList()">
							<el-icon><Refresh /></el-icon>
							{{ t('common.refresh') }}
						</el-button>
					</div>
				</div>

				<div
					v-loading="modelLoading"
					class="grid"
					:class="{ 'grid--empty': !allModels.length && !modelLoading }"
				>
					<el-empty
						v-if="!allModels.length && !modelLoading"
						:description="t('pages.model.empty')"
						class="empty"
					/>

					<div v-for="row in allModels" :key="row.id" class="card" @click="openDetailModel(row.id)">
						<div class="card-head">
							<div class="card-head__content">
								<div class="card-head__top">
									<div class="title-block">
										<div class="title">
											{{ row.title || row.name || t('pages.model.unnamedModel') }}
										</div>
										<div class="subtitle">{{ row.name || t('pages.model.unsetModelId') }}</div>
									</div>
									<div class="actions" @click.stop>
										<el-dropdown>
											<span class="actions-trigger">
												<el-icon>
													<MoreFilled />
												</el-icon>
											</span>
											<template #dropdown>
												<el-dropdown-menu>
													<el-dropdown-item @click="openDetailModel(row.id)">{{
														t('pages.model.detail')
													}}</el-dropdown-item>
													<el-dropdown-item v-permission="'edit'" @click="openEditModel(row.id)">{{
														t('pages.model.edit')
													}}</el-dropdown-item>
													<el-dropdown-item
														v-if="row.source === 'remote'"
														v-permission="'edit'"
														@click="updateModelCredentials(row.id)"
														divided
													>
														{{ t('pages.model.updateCredentials') }}
													</el-dropdown-item>
													<el-dropdown-item
														v-if="row.source === 'remote'"
														v-permission="'edit'"
														@click="deleteModelCredentials(row.id)"
													>
														<span class="danger-text">{{
															t('pages.model.deleteCredentials')
														}}</span>
													</el-dropdown-item>
													<el-dropdown-item
														v-permission="'del'"
														@click="deleteModelConfirm(row.id)"
														divided
													>
														<span class="danger-text">{{ t('common.delete') }}</span>
													</el-dropdown-item>
												</el-dropdown-menu>
											</template>
										</el-dropdown>
									</div>
								</div>

								<div class="badge-row">
									<span class="badge">{{ getModelTypeName(row.type) }}</span>
									<span class="badge subtle">{{ formatModelSource(row.source) }}</span>
								</div>
							</div>
						</div>

						<div class="desc">{{ row.description || t('pages.model.noDescription') }}</div>

						<div class="tags">
							<el-tag v-if="row.is_default" type="success" effect="light">{{
								t('pages.model.defaultTag')
							}}</el-tag>
							<el-tag :type="getModelStatusType(row.status)" effect="light">
								{{ formatModelStatus(row.status) }}
							</el-tag>
							<el-tag v-if="row.provider" type="info" effect="light">
								{{ row.provider }}
							</el-tag>
						</div>
					</div>
				</div>

				<div v-if="pagination.total > 0" class="pagination-wrap">
					<el-pagination
						v-model:current-page="pagination.pageIndex"
						v-model:page-size="pagination.pageSize"
						background
						layout="total, prev, pager, next"
						:total="pagination.total"
						@current-change="handlePageChange"
						@size-change="handleSizeChange"
					/>
				</div>
			</el-card>
		</div>

		<ModelDetailDialog
			v-model="showDetailDialog"
			:model="currentDetailModel"
			:check-loading="detailCheckLoading"
			:check-result="detailCheckResult"
			:get-model-type-name="getModelTypeName"
			@check="checkCurrentDetailModel"
		/>

		<ModelEditDrawer
			ref="modelFormRef"
			v-model="showModelDialog"
			:current-model-id="currentModelId"
			:model-form="modelForm"
			:model-rules="modelRules"
			:available-local-models="availableLocalModels"
			:providers="providers"
			:custom-header-list="customHeaderList"
			:thinking-control-options="thinkingControlOptions"
			:form-check-loading="formCheckLoading"
			:form-check-result="formCheckResult"
			:submit-loading="submitLoading"
			:query-base-url-suggestions="queryBaseUrlSuggestions"
			@source-change="handleSourceChange"
			@type-change="handleTypeChange"
			@provider-change="handleProviderChange"
			@add-custom-header="addCustomHeader"
			@remove-custom-header="removeCustomHeader"
			@check="checkModelFormConnection"
			@submit="submitModelForm"
		/>
	</div>
</template>

<script setup lang="ts">
import { computed, ref, reactive, onMounted, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Refresh, MoreFilled, Search, RefreshRight } from '@element-plus/icons-vue'
import { aiModel, ollama } from '@repo/api-service'
import { useI18n } from '@/composables/useI18n'
import ModelDetailDialog from './components/ModelDetailDialog.vue'
import ModelEditDrawer from './components/ModelEditDrawer.vue'
import type {
	ModelItem,
	ModelProvider,
	ModelCreateForm,
	ModelDetail,
	OllamaModel,
	modelType,
	ThinkingControlType
} from './types'

const { t } = useI18n()

const props = withDefaults(
	defineProps<{
		localOllamaModels?: OllamaModel[]
	}>(),
	{
		localOllamaModels: () => []
	}
)

const modelLoading = ref(false)
const submitLoading = ref(false)
const allModels = ref<ModelItem[]>([])
const providers = ref<ModelProvider[]>([])
const showModelDialog = ref(false)
const showDetailDialog = ref(false)
const currentModelId = ref<string | null>(null)
const currentDetailModel = ref<ModelDetail | null>(null)
const modelFormRef = ref()
const customHeaderList = ref<Array<{ key: string; value: string }>>([{ key: '', value: '' }])
const localModelOptions = ref<OllamaModel[]>([])
const thinkingControlOptions = computed<
	Array<{
		title: string
		description: string
		value: ThinkingControlType
	}>
>(() => [
	{
		title: t('pages.model.thinking.noneTitle'),
		description: t('pages.model.thinking.noneDescription'),
		value: 'none'
	},
	{
		title: 'chat_template_kwargs',
		description: t('pages.model.thinking.chatTemplateDescription'),
		value: 'chat_template_kwargs'
	},
	{
		title: 'enable_thinking',
		description: t('pages.model.thinking.enableThinkingDescription'),
		value: 'enable_thinking'
	},
	{
		title: 'thinking.type',
		description: t('pages.model.thinking.thinkingTypeDescription'),
		value: 'thinking_type'
	}
])
const detailCheckLoading = ref(false)
const detailCheckResult = reactive<{ success: boolean; message: string }>({
	success: false,
	message: ''
})
const formCheckLoading = ref(false)
const formCheckResult = reactive<{ success: boolean; message: string }>({
	success: false,
	message: ''
})
const searchForm = reactive({
	keyword: '',
	type: '',
	source: ''
})
const pagination = reactive({
	pageIndex: 1,
	pageSize: 20,
	total: 0
})

const availableLocalModels = computed(() =>
	props.localOllamaModels.length ? props.localOllamaModels : localModelOptions.value
)

const modelForm = reactive<ModelCreateForm>({
	source: 'local',
	type: 'KnowledgeQA',
	name: '',
	title: '',
	description: '',
	provider: '',
	base_url: '',
	api_key: '',
	custom_headers: {},
	dimension: undefined,
	truncate_prompt_tokens: undefined,
	supports_vision: false,
	thinking_control: 'none'
})

const modelRules = computed(() => ({
	name: [{ required: true, message: t('pages.model.messages.nameRequired'), trigger: 'change' }],
	title: [{ required: true, message: t('pages.model.messages.titleRequired'), trigger: 'blur' }],
	type: [{ required: true, message: t('pages.model.messages.typeRequired'), trigger: 'change' }],
	source: [
		{ required: true, message: t('pages.model.messages.sourceRequired'), trigger: 'change' }
	],
	dimension: [
		{
			validator: (_: any, value: number, callback: (error?: Error) => void) => {
				if (
					modelForm.source === 'remote' &&
					modelForm.type === 'Embedding' &&
					(!value || value <= 0)
				) {
					callback(new Error(t('pages.model.messages.dimensionRequired')))
					return
				}
				callback()
			},
			trigger: 'blur'
		}
	]
}))

const typeLabelMap = computed<Record<string, string>>(() => ({
	KnowledgeQA: t('pages.model.types.KnowledgeQA'),
	Embedding: t('pages.model.types.Embedding'),
	Rerank: t('pages.model.types.Rerank'),
	VLLM: t('pages.model.types.VLLM')
}))

// const filteredProviders = computed(() => {
// 	if (!modelForm.type) return providers.value
// 	return providers.value.filter((p) => getProviderModelTypes(p).includes(modelForm.type))
// })

// function getProviderModelTypes(provider: ModelProvider) {
// 	const typeMap: Record<string, ModelCreateForm['type']> = {
// 		chat: 'KnowledgeQA',
// 		embedding: 'Embedding',
// 		rerank: 'Rerank',
// 		vllm: 'VLLM',
// 		knowledgeqa: 'KnowledgeQA'
// 	}
// 	return (provider.modelTypes || [])
// 		.map((t) => typeMap[String(t).toLowerCase()] || (t as ModelCreateForm['type']))
// 		.filter((t) => ['KnowledgeQA', 'Embedding', 'Rerank', 'VLLM'].includes(t))
// }

// function getModelTypeLabel(type: ModelCreateForm['type']) {
// 	const map: Record<ModelCreateForm['type'], string> = {
// 		KnowledgeQA: 'LLM',
// 		Embedding: 'TEXT EMBEDDING',
// 		Rerank: 'RERANK',
// 		VLLM: 'VLLM'
// 	}
// 	return map[type]
// }

function getModelTypeName(type?: string) {
	if (!type) return '-'
	return typeLabelMap.value[type] || type
}

function formatModelSource(source?: string) {
	return source === 'local' ? t('pages.model.sources.localModel') : t('pages.model.sources.remote')
}

function formatModelStatus(status?: string) {
	if (!status) return t('pages.model.status.unknown')
	if (status === 'active') return t('pages.model.status.active')
	return status
}

function getModelStatusType(status?: string) {
	if (status === 'active') return 'success'
	if (!status) return 'info'
	return 'warning'
}

function resetDetailCheckResult() {
	detailCheckResult.success = false
	detailCheckResult.message = ''
}

function resetFormCheckResult() {
	formCheckResult.success = false
	formCheckResult.message = ''
}

async function runModelCheck(
	payload: Record<string, any>,
	resultState: { success: boolean; message: string }
) {
	resultState.message = ''
	try {
		const res = await aiModel.postModelCheck(payload as any)
		if (res?.isSuccess) {
			resultState.success = true
			resultState.message = res?.result?.message ?? t('pages.model.messages.checkSuccess')
			return true
		}
		resultState.success = false
		resultState.message = res?.result?.message || t('pages.model.messages.checkFailed')
		return false
	} catch {
		resultState.success = false
		resultState.message = t('pages.model.messages.checkFailed')
		return false
	}
}

async function openDetailModel(id: string) {
	const res = await aiModel.postModelInfo({ id })
	if (res.isSuccess) {
		currentDetailModel.value = res.result as ModelDetail
		resetDetailCheckResult()
		showDetailDialog.value = true
	}
}

/**根据模型类型获取模型提供者 */
async function getProviders(type?: modelType) {
	const res = await aiModel.postModelProviders({ model_type: type! })
	if (res.isSuccess) providers.value = (res.result || []) as ModelProvider[]
}

async function getAllModelList() {
	modelLoading.value = true
	try {
		const res = await aiModel.postModelPageList({
			keyword: searchForm.keyword,
			type: searchForm.type,
			source: searchForm.source,
			pageIndex: pagination.pageIndex,
			pageSize: pagination.pageSize
		})
		if (res.isSuccess) {
			allModels.value = (res.result.model || []) as ModelItem[]
			pagination.total = res.result.totalCount || 0
			pagination.pageIndex = res.result.currentPage || pagination.pageIndex
			pagination.pageSize = res.result.pageSize || pagination.pageSize
		}
	} finally {
		modelLoading.value = false
	}
}

async function loadLocalModels() {
	if (props.localOllamaModels.length) return
	try {
		const res = await ollama.postOllamaModels({})
		if (res?.isSuccess) {
			localModelOptions.value = (res.result || []) as OllamaModel[]
		}
	} catch {
		localModelOptions.value = []
	}
}

function handleSearch() {
	pagination.pageIndex = 1
	getAllModelList()
}

function handleResetSearch() {
	searchForm.keyword = ''
	searchForm.type = ''
	searchForm.source = ''
	pagination.pageIndex = 1
	pagination.pageSize = 20
	getAllModelList()
}

function handlePageChange(page: number) {
	pagination.pageIndex = page
	getAllModelList()
}

function handleSizeChange(size: number) {
	pagination.pageSize = size
	pagination.pageIndex = 1
	getAllModelList()
}

function openCreateModel() {
	resetModelForm()
	showModelDialog.value = true
}

// function openCreateModelByProvider(provider: ModelProvider) {
// 	resetModelForm()
// 	modelForm.source = 'remote'
// 	modelForm.provider = provider.value
// 	modelForm.type = getProviderModelTypes(provider)[0] || 'KnowledgeQA'
// 	modelForm.base_url = getDefaultUrlByType(provider)
// 	if (modelForm.type === 'VLLM') modelForm.supports_vision = true
// 	showModelDialog.value = true
// }

async function openEditModel(id: string) {
	resetModelForm()
	currentModelId.value = id
	const res = await aiModel.postModelInfo({ id })
	if (res.isSuccess) {
		const data = res.result
		const currentHeaders = ((data as any)?.parameters?.custom_headers || {}) as Record<
			string,
			string
		>
		const headerRows = Object.entries(currentHeaders).map(([key, value]) => ({
			key,
			value: String(value ?? '')
		}))
		const extraConfig = ((data as any)?.parameters?.extra_config ||
			(data as any)?.extra_config ||
			{}) as {
			thinking_control?: ThinkingControlType
		}
		customHeaderList.value = headerRows.length ? headerRows : [{ key: '', value: '' }]
		Object.assign(modelForm, {
			source: data.source,
			type: data.type,
			name: data.name,
			title: data.title,
			description: data.description,
			provider: data.provider,
			base_url: data.parameters.base_url,
			api_key: data.parameters.api_key,
			custom_headers: currentHeaders,
			dimension: data.parameters?.embedding_parameters?.dimension,
			truncate_prompt_tokens: data.parameters?.embedding_parameters?.truncate_prompt_tokens,
			supports_vision: Boolean((data as any)?.parameters?.supports_vision),
			thinking_control: extraConfig.thinking_control || 'none',
			is_default: data.is_default
		})
	}
	showModelDialog.value = true
}

function resetModelForm() {
	currentModelId.value = null
	customHeaderList.value = [{ key: '', value: '' }]
	resetFormCheckResult()
	Object.assign(modelForm, {
		source: 'local',
		type: 'KnowledgeQA',
		name: '',
		title: '',
		description: '',
		provider: '',
		base_url: '',
		api_key: '',
		custom_headers: {},
		dimension: undefined,
		truncate_prompt_tokens: undefined,
		supports_vision: false,
		thinking_control: 'none',
		is_default: false
	})
}
function addCustomHeader() {
	customHeaderList.value.push({ key: '', value: '' })
}
function removeCustomHeader(index: number) {
	if (customHeaderList.value.length === 1) {
		customHeaderList.value[0] = { key: '', value: '' }
		return
	}
	customHeaderList.value.splice(index, 1)
}

function handleSourceChange() {
	modelForm.name = ''
	modelForm.provider = ''
	modelForm.base_url = ''
	modelForm.thinking_control = 'none'
	resetFormCheckResult()
}

async function handleTypeChange() {
	modelForm.provider = ''
	modelForm.base_url = ''
	resetFormCheckResult()
	if (modelForm.type === 'VLLM') {
		modelForm.supports_vision = true
		return
	}
	if (modelForm.type === 'KnowledgeQA') {
		modelForm.supports_vision = modelForm.supports_vision ?? false
		modelForm.thinking_control = getDefaultThinkingControl(modelForm.provider)
		return
	}
	modelForm.supports_vision = false
	modelForm.thinking_control = 'none'
	modelForm.dimension = undefined
	modelForm.truncate_prompt_tokens = undefined
	// getProviders(modelForm.type)
}

function handleProviderChange() {
	const provider = providers.value.find((p) => p.value === modelForm.provider)
	if (provider) modelForm.base_url = getDefaultUrlByType(provider) || ''
	modelForm.thinking_control = getDefaultThinkingControl(modelForm.provider)
	resetFormCheckResult()
}

function getDefaultThinkingControl(provider?: string): ThinkingControlType {
	const providerValue = (provider || '').toLowerCase()
	if (providerValue.includes('dashscope') || providerValue.includes('aliyun')) {
		return 'enable_thinking'
	}
	if (
		providerValue.includes('volc') ||
		providerValue.includes('ark') ||
		providerValue.includes('lkeap') ||
		providerValue.includes('tencent')
	) {
		return 'thinking_type'
	}
	if (
		providerValue.includes('nvidia') ||
		providerValue.includes('nim') ||
		providerValue.includes('vllm')
	) {
		return 'chat_template_kwargs'
	}
	return 'none'
}

function getDefaultUrlByType(provider: ModelProvider) {
	const typeToDefaultUrlKey: Record<string, keyof ModelProvider['defaultUrls']> = {
		KnowledgeQA: 'chat',
		Embedding: 'embedding',
		Rerank: 'rerank',
		VLLM: 'vllm'
	}
	const defaultUrlKey = typeToDefaultUrlKey[modelForm.type] || 'chat'
	return provider.defaultUrls?.[defaultUrlKey] || ''
}

function queryBaseUrlSuggestions(
	queryString: string,
	cb: (results: Array<{ value: string }>) => void
) {
	const provider = providers.value.find((p) => p.value === modelForm.provider)
	if (!provider) return cb([])
	const defaultUrl = getDefaultUrlByType(provider)
	if (!defaultUrl) return cb([])
	const list = [{ value: defaultUrl }]
	const keyword = (queryString || '').trim().toLowerCase()
	cb(keyword ? list.filter((item) => item.value.toLowerCase().includes(keyword)) : list)
}

function buildCheckParams() {
	const payload: Record<string, any> = {
		name: modelForm.name,
		type: modelForm.type,
		source: modelForm.source,
		provider: modelForm.provider,
		api_key: modelForm.api_key
	}
	if (modelForm.type === 'Embedding') {
		payload.truncate_prompt_tokens = modelForm.truncate_prompt_tokens ?? 0
	}
	return payload
}

async function checkCurrentDetailModel() {
	if (!currentDetailModel.value || currentDetailModel.value.source !== 'remote') return
	detailCheckLoading.value = true
	try {
		const detail = currentDetailModel.value
		const payload: Record<string, any> = {
			name: detail.name,
			type: detail.type,
			source: detail.source,
			provider: detail.provider,
			api_key: '',
			id: detail.id
		}
		if (detail.type === 'Embedding') {
			payload.truncate_prompt_tokens =
				detail.parameters?.embedding_parameters?.truncate_prompt_tokens ?? 0
		}
		await runModelCheck(payload, detailCheckResult)
	} finally {
		detailCheckLoading.value = false
	}
}

async function checkModelFormConnection() {
	if (modelForm.source !== 'remote') return
	const valid = await modelFormRef.value
		?.validateField?.(['type', 'name', 'source'])
		.then(() => true)
		.catch(() => false)
	if (!valid) return
	if (!modelForm.provider || !modelForm.api_key) {
		formCheckResult.success = false
		formCheckResult.message = t('pages.model.messages.providerAndKeyRequired')
		return
	}
	formCheckLoading.value = true
	try {
		await runModelCheck(buildCheckParams(), formCheckResult)
	} finally {
		formCheckLoading.value = false
	}
}

async function submitModelForm() {
	await modelFormRef.value?.validate(async (valid: boolean) => {
		if (!valid) return
		submitLoading.value = true
		try {
			const customHeaders: Record<string, string> = {}
			for (const item of customHeaderList.value) {
				const key = item.key.trim()
				if (!key) continue
				customHeaders[key] = item.value
			}
			// try {
			// 	if (
			// 		typeof modelForm.custom_headers === 'string' &&
			// 		modelForm.custom_headers.trim().startsWith('{')
			// 	) {
			// 		Object.assign(customHeaders, JSON.parse(modelForm.custom_headers))
			// 	}
			// } catch {
			// 	ElMessage.error('自定义请求头 JSON 格式错误')
			// 	return
			// }
			if (modelForm.source === 'remote') {
				const checkSuccess = await runModelCheck(buildCheckParams(), formCheckResult)
				if (!checkSuccess) {
					ElMessage.error(formCheckResult.message || t('pages.model.messages.modelUnavailable'))
					return
				}
			}

			const params = {
				name: modelForm.name,
				title: modelForm.title,
				description: modelForm.description,
				type: modelForm.type,
				source: modelForm.source,
				provider: modelForm.source === 'local' ? 'ollama' : modelForm.provider!,
				base_url: modelForm.base_url,
				api_key: modelForm.api_key,
				custom_headers: customHeaders,
				supports_vision:
					modelForm.type === 'VLLM'
						? true
						: modelForm.type === 'KnowledgeQA'
							? !!modelForm.supports_vision
							: false,
				dimension: modelForm.type === 'Embedding' ? modelForm.dimension : undefined,
				truncate_prompt_tokens:
					modelForm.type === 'Embedding' ? modelForm.truncate_prompt_tokens : undefined,
				extra_config: {
					thinking_control:
						modelForm.source === 'remote' && modelForm.type === 'KnowledgeQA'
							? modelForm.thinking_control
							: 'none'
				}
			}
			if (currentModelId.value) {
				await aiModel.postModelUpdate({ id: currentModelId.value, ...params } as any)
				ElMessage.success(t('pages.model.messages.updateSuccess'))
			} else {
				await aiModel.postModelCreate(params as any)
				ElMessage.success(t('pages.model.messages.createSuccess'))
			}
			showModelDialog.value = false
			getAllModelList()
		} catch {
			ElMessage.error(t('pages.model.messages.submitFailed'))
		} finally {
			submitLoading.value = false
		}
	})
}

async function deleteModelConfirm(id: string) {
	ElMessageBox.confirm(t('pages.model.messages.deleteConfirm')).then(async () => {
		await aiModel.postModelOpenApiDelete({ id })
		ElMessage.success(t('pages.model.messages.deleteSuccess'))
		getAllModelList()
	})
}

async function updateModelCredentials(id: string) {
	try {
		const { value } = await ElMessageBox.prompt(
			t('pages.model.messages.updateCredentialPrompt'),
			t('pages.model.messages.updateCredentialTitle'),
			{
				confirmButtonText: t('common.confirm'),
				cancelButtonText: t('common.cancel'),
				inputType: 'password',
				inputValidator: (value) => !!value?.trim() || t('pages.model.messages.apiKeyRequired')
			}
		)
		await aiModel.postModelCredentials({ id, api_key: value.trim() })
		ElMessage.success(t('pages.model.messages.credentialUpdateSuccess'))
		getAllModelList()
	} catch (error) {
		if (error !== 'cancel' && error !== 'close') {
			ElMessage.error(t('pages.model.messages.credentialUpdateFailed'))
		}
	}
}

async function deleteModelCredentials(id: string) {
	try {
		await ElMessageBox.confirm(
			t('pages.model.messages.deleteCredentialConfirm'),
			t('common.dialog.tip'),
			{
				type: 'warning'
			}
		)
		await aiModel.postModelDeleteCredentials({ id })
		ElMessage.success(t('pages.model.messages.credentialDeleteSuccess'))
		getAllModelList()
	} catch (error) {
		if (error !== 'cancel' && error !== 'close') {
			ElMessage.error(t('pages.model.messages.credentialDeleteFailed'))
		}
	}
}

watch(
	() => modelForm.type,
	() => {
		if (modelForm.type) {
			getProviders(modelForm.type)
		}
	},
	{ immediate: true }
)

onMounted(() => {
	// getProviders()
	loadLocalModels()
	getAllModelList()
	window.addEventListener('open-import-ollama-model', (e: any) => {
		resetModelForm()
		modelForm.source = 'local'
		modelForm.name = e.detail
		modelForm.title = e.detail
		showModelDialog.value = true
	})
})
</script>

<style scoped lang="less">
.management-page {
	padding: 24px;
	min-height: 100%;
	box-sizing: border-box;
}

.page-head {
	margin-bottom: 20px;

	h1 {
		margin: 0;
		font-size: 28px;
		color: var(--text-primary);
	}

	p {
		margin: 6px 0 0;
		font-size: 14px;
		color: var(--text-secondary);
	}
}

.model-manage {
	width: 100%;
}

.action-bar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 12px;
}

.action-bar__left,
.action-bar__right {
	display: flex;
	align-items: center;
	gap: 12px;
	flex-wrap: wrap;
}

.toolbar-actions {
	display: flex;
	align-items: center;
	gap: 8px;

	.el-button + .el-button {
		margin-left: 0;
	}
}

.list-card {
	border-radius: 18px;
	margin-bottom: 16px;
}

.search-input {
	width: 240px;
}

.pagination-wrap {
	display: flex;
	justify-content: flex-end;
	margin-top: 16px;
}

.grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
	gap: 16px;
	min-height: 240px;
}

.grid--empty {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 360px;
}

.card {
	overflow: hidden;
	border-radius: 20px;
	border: 1px solid var(--border-light);
	background: var(--bg-base);
	box-shadow: var(--shadow-sm);
	cursor: pointer;
	padding: 16px;
	display: flex;
	flex-direction: column;
	gap: 14px;
	transition:
		transform 0.22s ease,
		box-shadow 0.22s ease,
		border-color 0.22s ease;
}

.card:hover {
	transform: translateY(-3px);
	border-color: var(--border-base);
	box-shadow: var(--shadow-md);
}

.card-head {
	padding: 14px 16px;
	border-radius: 18px;
	background: var(--card-bg-unselected);
}

.card-head__content {
	min-width: 0;
}

.card-head__top {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 12px;
}

.title-block {
	min-width: 0;
}

.title {
	font-size: 18px;
	font-weight: 700;
	line-height: 1.25;
	color: var(--text-strong);
	word-break: break-word;
}

.subtitle {
	margin-top: 6px;
	font-size: 13px;
	color: var(--text-secondary);
	word-break: break-all;
}

.badge-row {
	margin-top: 10px;
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.badge {
	padding: 5px 10px;
	border-radius: 999px;
	background: var(--bg-overlay);
	font-size: 12px;
	color: var(--text-primary);
	border: 1px solid var(--border-light);
}

.badge.subtle {
	background: var(--text-strong);
	color: var(--bg-base);
	border-color: transparent;
}

.desc {
	min-height: 44px;
	color: var(--text-secondary);
	font-size: 14px;
	line-height: 1.65;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.tags {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.actions {
	display: flex;
	justify-content: flex-end;
}

.actions-trigger {
	width: 30px;
	height: 30px;
	border-radius: 999px;
	display: grid;
	place-items: center;
	color: var(--text-secondary);
	background: var(--bg-overlay);
	transition:
		background 0.2s ease,
		color 0.2s ease;
}

.actions-trigger:hover {
	background: var(--bg-container);
	color: var(--text-strong);
}

.danger-text {
	color: var(--el-color-danger);
}

.empty {
	width: 100%;
	min-height: 360px;
	display: flex;
	align-items: center;
	justify-content: center;
	grid-column: span 4;
}

@media (max-width: 768px) {
	.search-input {
		width: 100%;
	}
}
</style>
