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

		<el-card class="list-card">
			<div class="toolbar">
				<div class="toolbar-left">
					<el-input
						v-model="keyword"
						clearable
						:placeholder="t('pages.prompt.searchPlaceholder')"
						class="search-input"
						@keyup.enter="loadList(1)"
					>
						<template #prefix>
							<el-icon>
								<Search />
							</el-icon>
						</template>
					</el-input>
					<el-select
						v-model="type"
						clearable
						:placeholder="t('pages.prompt.type')"
						style="width: 160px"
						:options="typeList"
						@change="loadList(1)"
					></el-select>
					<div class="toolbar-actions">
						<el-button type="primary" @click="loadList(1)">
							<el-icon><Search /></el-icon>
							{{ t('common.search') }}
						</el-button>
						<el-button @click="handleReset">
							<el-icon><RefreshRight /></el-icon>
							{{ t('common.reset') }}
						</el-button>
					</div>
				</div>
				<div class="toolbar-right">
					<el-button type="primary" @click="openCreate">
						<el-icon>
							<Plus />
						</el-icon>
						{{ t('pages.prompt.createPrompt') }}
					</el-button>
				</div>
			</div>

			<div v-loading="loading" class="card-grid">
				<el-empty v-if="!visibleList.length && !loading" :description="t('pages.prompt.noPrompt')" class="empty" />
				<div v-for="item in visibleList" :key="item.id" class="resource-card">
					<div class="resource-card__top">
						<div>
							<div class="resource-card__title flex items-center gap-4px">
								<el-tag v-if="item.is_builtin" type="success" effect="light">{{ t('pages.prompt.builtIn') }}</el-tag
								>{{ item.name }}
							</div>

							<div class="resource-card__desc">{{ item.description || t('pages.prompt.noDescription') }}</div>
						</div>
						<el-dropdown :hide-on-click="false">
							<span class="cursor-pointer">
								<el-icon>
									<MoreFilled />
								</el-icon>
							</span>
							<template #dropdown>
								<el-dropdown-menu>
									<el-dropdown-item>
										<el-button link type="primary" @click="openDetail(item)">{{ t('pages.prompt.detail') }}</el-button>
									</el-dropdown-item>
									<el-dropdown-item>
										<el-button link type="primary" @click="openEdit(item)">{{ t('common.edit') }}</el-button>
									</el-dropdown-item>
									<el-dropdown-item>
										<el-button link type="danger" @click="removeItem(item.id)">{{ t('common.delete') }}</el-button>
									</el-dropdown-item>
								</el-dropdown-menu>
							</template>
						</el-dropdown>
					</div>
					<div class="resource-card__meta">
						<span>{{ t('pages.prompt.typeLabel') }}{{ formatType(item.type) }}</span>
					</div>
					<div class="resource-card__content">{{ shortText(item.content) }}</div>
				</div>
			</div>

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

		<el-drawer
			v-model="drawerVisible"
			:title="currentId ? t('pages.prompt.editPrompt') : t('pages.prompt.createPromptTitle')"
			direction="rtl"
			size="760px"
		>
			<el-form ref="formRef" :model="form" :rules="rules" label-position="top">
				<el-form-item :label="t('pages.prompt.name')" prop="name">
					<el-input v-model="form.name" />
				</el-form-item>
				<el-form-item :label="t('pages.prompt.description')" prop="description">
					<el-input v-model="form.description" type="textarea" :rows="2" />
				</el-form-item>
				<el-form-item :label="t('pages.prompt.content')" prop="content">
					<el-input v-model="form.content" type="textarea" :rows="8" />
				</el-form-item>
				<el-form-item :label="t('pages.prompt.userPrompt')" prop="user">
					<el-input v-model="form.user" type="textarea" :rows="4" />
				</el-form-item>
				<div class="grid-2">
					<el-form-item :label="t('pages.prompt.type')" prop="type">
						<el-select v-model="form.type" style="width: 100%">
							<el-option label="系统提示词" value="system-prompt" />
							<el-option label="agent 系统提示词" value="agent-system-prompt" />
							<el-option label="改写提示词" value="rewrite" />
							<el-option label="回退提示词" value="fallback" />
							<el-option label="上下文模板" value="context-template" />
						</el-select>
					</el-form-item>
					<el-form-item :label="t('pages.prompt.isDefault')" prop="is_default">
						<el-switch v-model="form.is_default" />
					</el-form-item>
				</div>
				<div class="grid-2">
					<el-form-item :label="t('pages.prompt.includeKnowledge')" prop="has_knowledge_base">
						<el-switch v-model="form.has_knowledge_base" />
					</el-form-item>
					<el-form-item :label="t('pages.prompt.includeWebSearch')" prop="has_web_search">
						<el-switch v-model="form.has_web_search" />
					</el-form-item>
				</div>
			</el-form>
			<template #footer>
				<div class="drawer-footer">
					<el-button @click="drawerVisible = false">{{ t('common.cancel') }}</el-button>
					<el-button type="primary" :loading="submitLoading" @click="handleSubmit">{{ t('common.save') }}</el-button>
				</div>
			</template>
		</el-drawer>

		<el-drawer v-model="detailVisible" :title="t('pages.prompt.promptDetail')" width="760px">
			<el-descriptions v-if="detailItem" :column="1" direction="vertical">
				<el-descriptions-item :label="t('pages.prompt.name')">{{ detailItem.name }}</el-descriptions-item>
				<el-descriptions-item :label="t('pages.prompt.type')">{{ formatType(detailItem.type) }}</el-descriptions-item>
				<el-descriptions-item :label="t('pages.prompt.description')">{{
					detailItem.description || '-'
				}}</el-descriptions-item>
				<el-descriptions-item :label="t('pages.prompt.content')">
					<div class="w-full p-12px box-border border-1px rounded-md border-solid border-gray-200">
						<SMarkdown :markdown="detailItem.content" />
					</div>
				</el-descriptions-item>
			</el-descriptions>
		</el-drawer>
	</div>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Search, MoreFilled, RefreshRight } from '@element-plus/icons-vue'
import { resource } from '@repo/api-service'
import SMarkdown from '@/components/Chat/SMarkdown.vue'
import { useI18n } from '@/composables/useI18n'

type PromptPageResponse = Awaited<ReturnType<typeof resource.postPromptTemplatePageList>>
type PromptPageResult = NonNullable<PromptPageResponse['result']>
type PromptItem = PromptPageResult['model'][number]

const { t } = useI18n()

const keyword = ref('')
const type = ref('')
const loading = ref(false)
const submitLoading = ref(false)
const drawerVisible = ref(false)
const detailVisible = ref(false)
const detailItem = ref<PromptItem | null>(null)
const currentId = ref('')
const formRef = ref()

const pagination = reactive({
	pageIndex: 1,
	pageSize: 20,
	totalCount: 0,
	totalPages: 0
})

const list = ref<PromptItem[]>([])

const form = reactive({
	name: '',
	description: '',
	content: '',
	user: '',
	type: 'system-prompt',
	is_default: false,
	has_knowledge_base: false,
	has_web_search: false
})

const rules = {
	name: [{ required: true, message: t('pages.prompt.pleaseInputName'), trigger: 'blur' }],
	content: [{ required: true, message: t('pages.prompt.pleaseInputContent'), trigger: 'blur' }],
	type: [{ required: true, message: t('pages.prompt.pleaseSelectType'), trigger: 'change' }]
}

const visibleList = computed(() => list.value)

const typeMap = computed<Record<string, string>>(() => ({
	'system': t('pages.prompt.typeMap.system'),
	'agent_system': t('pages.prompt.typeMap.agentSystem'),
	'rewrite': t('pages.prompt.typeMap.rewrite'),
	'fallback': t('pages.prompt.typeMap.fallback'),
	'context_template': t('pages.prompt.typeMap.contextTemplate'),
	'generate_title': t('pages.prompt.typeMap.generateTitle'),
	'generate_summary': t('pages.prompt.typeMap.generateSummary'),
	'keyword_extraction': t('pages.prompt.typeMap.keywordExtraction')
}))

const typeList = computed(() => Object.keys(typeMap.value).map((type) => ({ label: typeMap.value[type], value: type })))

function formatType(type?: string) {
	return typeMap.value[type || ''] || type || '-'
}

function shortText(text?: string) {
	if (!text) return '-'
	return text.length > 120 ? `${text.slice(0, 120)}...` : text
}

function resetForm() {
	currentId.value = ''
	form.name = ''
	form.description = ''
	form.content = ''
	form.user = ''
	form.type = 'system-prompt'
	form.is_default = false
	form.has_knowledge_base = false
	form.has_web_search = false
}

async function loadList(pageIndex = 1) {
	loading.value = true
	try {
		const res = await resource.postPromptTemplatePageList({
			keyword: keyword.value,
			type: type.value,
			pageIndex,
			pageSize: pagination.pageSize
		})
		if (res.isSuccess && res.result) {
			list.value = (res.result.model || []) as PromptItem[]
			pagination.pageIndex = res.result.currentPage || pageIndex
			pagination.totalCount = res.result.totalCount || 0
			pagination.totalPages = res.result.totalPages || 0
			pagination.pageSize = res.result.pageSize || pagination.pageSize
		}
	} finally {
		loading.value = false
	}
}

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

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

function handleReset() {
	keyword.value = ''
	loadList(1)
}

function openCreate() {
	resetForm()
	drawerVisible.value = true
}

function openEdit(item: PromptItem) {
	resetForm()
	currentId.value = item.id
	form.name = item.name || ''
	form.description = item.description || ''
	form.content = item.content || ''
	form.user = item.user || ''
	form.type = item.type || 'system-prompt'
	form.has_knowledge_base = !!item.has_knowledge_base
	form.has_web_search = !!item.has_web_search
	drawerVisible.value = true
}

function openDetail(item: PromptItem) {
	detailItem.value = item
	detailVisible.value = true
}

async function handleSubmit() {
	await formRef.value?.validate(async (valid: boolean) => {
		if (!valid) return
		submitLoading.value = true
		try {
			const payload = {
				name: form.name,
				description: form.description,
				content: form.content,
				user: form.user,
				type: form.type,
				is_default: form.is_default,
				has_knowledge_base: form.has_knowledge_base,
				has_web_search: form.has_web_search
			}
			if (currentId.value) {
				await resource.postPromptTemplateUpdate({ id: currentId.value, ...(payload as any) })
				ElMessage.success(t('pages.prompt.updateSuccess'))
			} else {
				await resource.postPromptTemplateCreate(payload as any)
				ElMessage.success(t('pages.prompt.createSuccess'))
			}
			drawerVisible.value = false
			loadList(pagination.pageIndex)
		} catch {
			ElMessage.error(t('pages.prompt.saveFailed'))
		} finally {
			submitLoading.value = false
		}
	})
}

async function removeItem(id: string) {
	try {
		await ElMessageBox.confirm(t('pages.prompt.confirmDelete'), t('pages.prompt.tip'), { type: 'warning' })
		await resource.postPromptTemplateOpenApiDelete({ id })
		ElMessage.success(t('pages.prompt.deleteSuccess'))
		loadList(pagination.pageIndex)
	} catch {
		// ignore
	}
}

onMounted(() => {
	loadList(1)
})
</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);
	}
}

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

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

.toolbar-left,
.toolbar-right {
	display: flex;
	align-items: center;
	gap: 10px;
	flex-wrap: wrap;
}

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

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

.search-input {
	width: 280px;
}

.card-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
	gap: 16px;
	min-height: 200px;
	margin: 16px 0;
}

.resource-card {
	padding: 16px;
	border-radius: 18px;
	border: 1px solid var(--border-light);
	background: var(--bg-base);
	box-shadow: var(--shadow-sm);
}

.resource-card__top {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 10px;
}

.resource-card__title {
	font-size: 18px;
	font-weight: 700;
	color: var(--text-primary);
}

.resource-card__desc {
	margin-top: 6px;
	color: var(--text-tertiary);
	font-size: 13px;
}

.resource-card__meta {
	display: flex;
	flex-wrap: wrap;
	gap: 8px 12px;
	margin-top: 12px;
	font-size: 12px;
	color: var(--text-tertiary);
}

.resource-card__content {
	margin-top: 12px;
	padding: 12px;
	border-radius: 12px;
	background: var(--bg-container);
	color: var(--text-primary);
	font-size: 13px;
	line-height: 1.6;
	white-space: pre-wrap;
}

.resource-card__actions {
	display: flex;
	justify-content: flex-end;
	gap: 8px;
	margin-top: 12px;
}

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

.grid-2 {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 12px;
}

.drawer-footer {
	display: flex;
	justify-content: flex-end;
	gap: 10px;
}

.empty {
	padding: 24px 0;
	grid-column: span 4;
}

@media (max-width: 768px) {
	.toolbar,
	.grid-2 {
		grid-template-columns: 1fr;
	}

	.search-input {
		width: 100%;
	}
}
</style>
