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

		<el-card class="list-card" v-loading="pageLoading">
			<!-- 搜索和操作栏 -->
			<div class="toolbar">
				<el-form :model="searchForm" inline class="search-form">
					<el-form-item>
						<el-input
							v-model="searchForm.keyword"
							:placeholder="t('pages.vectorStore.searchPlaceholder')"
							clearable
							@clear="handleSearch"
							@keyup.enter="handleSearch"
						>
							<template #prefix>
								<el-icon><Search /></el-icon>
							</template>
						</el-input>
					</el-form-item>
					<el-form-item>
						<el-button type="primary" @click="handleSearch">
							<el-icon><Search /></el-icon>
							{{ t('common.search') }}
						</el-button>
						<el-button @click="handleReset">
							<el-icon><RefreshRight /></el-icon>
							{{ t('common.reset') }}
						</el-button>
					</el-form-item>
				</el-form>
				<div class="toolbar-actions">
					<el-button type="primary" @click="openCreate">
						<el-icon><Plus /></el-icon>
						{{ t('pages.vectorStore.create') }}
					</el-button>
				</div>
			</div>

			<!-- 卡片列表 -->
			<div class="card-grid">
				<div v-for="item in list" :key="item.id" class="card">
					<div class="card-head">
						<div class="card-head__top">
							<div class="title-block">
								<div class="title">{{ item.name }}</div>
								<div class="subtitle">{{ formatEngineType(item.engine_type) }}</div>
							</div>
							<div class="actions">
								<el-dropdown>
									<span class="actions-trigger">
										<el-icon><MoreFilled /></el-icon>
									</span>
									<template #dropdown>
										<el-dropdown-menu>
											<el-dropdown-item @click="handleTestConnection(item)">
												{{ t('pages.vectorStore.testConnection') }}
											</el-dropdown-item>
											<el-dropdown-item @click="openEdit(item)">
												{{ t('common.edit') }}
											</el-dropdown-item>
											<el-dropdown-item @click="openDetail(item)">
												{{ t('common.details') }}
											</el-dropdown-item>
											<el-dropdown-item divided @click="handleDeleteConfirm(item)">
												{{ t('common.delete') }}
											</el-dropdown-item>
										</el-dropdown-menu>
									</template>
								</el-dropdown>
							</div>
						</div>
					</div>

					<div class="card-info">
						<div class="info-row">
							<span class="info-label">{{ t('pages.vectorStore.connectionAddr') }}</span>
							<span class="info-value">{{ item.connection_config?.addr || '-' }}</span>
						</div>
						<div class="info-row">
							<span class="info-label">创建时间</span>
							<span class="info-value">{{ item.creationTime || '-' }}</span>
						</div>
					</div>

					<!-- <div class="tags">
						<el-tag :type="item.source === 'system' ? 'warning' : 'info'" effect="light">
							{{
								item.source === 'system'
									? t('pages.vectorStore.sourceSystem')
									: t('pages.vectorStore.sourceUser')
							}}
						</el-tag>
					</div> -->
				</div>
				<el-empty v-if="!list.length" class="empty" :description="t('pages.vectorStore.empty')" />
			</div>

			<!-- 分页 -->
			<div class="pagination" v-if="pagination.totalCount">
				<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="loadList"
				/>
			</div>
		</el-card>

		<!-- 创建/编辑抽屉 -->
		<VectorEditDrawer
			v-model:visible="editDrawerVisible"
			:is-edit="isEdit"
			:edit-id="editId"
			:engine-types="engineTypes"
			:initial-data="editData"
			@saved="loadList"
		/>

		<!-- 详情抽屉 -->
		<VectorDetailDrawer
			v-model:visible="detailDrawerVisible"
			:target-id="detailTargetId"
			:engine-types="engineTypes"
		/>
	</div>
</template>

<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { MoreFilled, Plus, Refresh, RefreshRight, Search } from '@element-plus/icons-vue'
import { vector } from '@repo/api-service'
import { useI18n } from '@/composables/useI18n'
import VectorEditDrawer from './VectorEditDrawer.vue'
import VectorDetailDrawer from './VectorDetailDrawer.vue'
import type { EngineTypeConfig, VectorStoreItem } from './types'

const { t } = useI18n()

// --- 状态 ---
const pageLoading = ref(false)
const editDrawerVisible = ref(false)
const detailDrawerVisible = ref(false)
const isEdit = ref(false)
const editId = ref('')
const editData = ref<VectorStoreItem | null>(null)
const detailTargetId = ref('')
const list = ref<VectorStoreItem[]>([])
const engineTypes = ref<EngineTypeConfig[]>([])

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

// --- 方法 ---
function formatEngineType(type: string) {
	const config = engineTypes.value.find((item) => item.type === type)
	return config?.display_name || type.toUpperCase()
}

async function loadTypes() {
	try {
		const res = await vector.postTypes({})
		if (res?.isSuccess && res.result) {
			engineTypes.value = res.result as EngineTypeConfig[]
		}
	} catch {
		ElMessage.error(t('pages.vectorStore.loadTypesFailed'))
	}
}

async function loadList() {
	pageLoading.value = true
	try {
		const res = await vector.postPageList({
			keyword: searchForm.keyword,
			pageIndex: pagination.pageIndex,
			pageSize: pagination.pageSize
		})
		if (res?.isSuccess && res.result) {
			const data = res.result?.model as any
			if (Array.isArray(data)) {
				list.value = data
				pagination.totalCount = data.length
			} else {
				list.value = data.list || data.items || data.data || []
				pagination.totalCount = data.totalCount ?? data.total ?? list.value.length
			}
		}
	} catch {
		ElMessage.error(t('pages.vectorStore.loadListFailed'))
	} finally {
		pageLoading.value = false
	}
}

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

function handleReset() {
	searchForm.keyword = ''
	pagination.pageIndex = 1
	loadList()
}

function openCreate() {
	isEdit.value = false
	editId.value = ''
	editData.value = null
	editDrawerVisible.value = true
}

function openEdit(row: VectorStoreItem) {
	isEdit.value = true
	editId.value = row.id
	editData.value = row
	editDrawerVisible.value = true
}

function openDetail(row: VectorStoreItem) {
	detailTargetId.value = row.id
	detailDrawerVisible.value = true
}

async function handleDeleteConfirm(row: VectorStoreItem) {
	try {
		await ElMessageBox.confirm(
			t('pages.vectorStore.deleteConfirm'),
			t('pages.vectorStore.deleteConfirmTitle'),
			{ type: 'warning' }
		)
		await handleDelete(row)
	} catch {
		// cancelled
	}
}

async function handleDelete(row: VectorStoreItem) {
	try {
		const res = await vector.postOpenApiDelete({ id: row.id })
		if (res?.isSuccess) {
			ElMessage.success(t('pages.vectorStore.deleteSuccess'))
			await loadList()
		} else {
			ElMessage.error(t('pages.vectorStore.deleteFailed'))
		}
	} catch {
		ElMessage.error(t('pages.vectorStore.deleteFailed'))
	}
}

async function handleTestConnection(row: VectorStoreItem) {
	try {
		const res = await vector.postConnectTestId({ id: row.id })
		if (res?.isSuccess) {
			ElMessage.success(`${row.name} ${t('pages.vectorStore.testSuccess')}`)
		} else {
			ElMessage.error(`${row.name} ${t('pages.vectorStore.testFailed')}`)
		}
	} catch {
		ElMessage.error(`${row.name} ${t('pages.vectorStore.testFailed')}`)
	}
}

onMounted(async () => {
	pageLoading.value = true
	try {
		await Promise.all([loadTypes(), loadList()])
	} finally {
		pageLoading.value = false
	}
})
</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: flex-start;
	justify-content: space-between;
	gap: 16px;
	flex-wrap: wrap;
	margin-bottom: 16px;
}

.search-form {
	:deep(.el-form-item) {
		margin-bottom: 0;
	}

	:deep(.el-form-item + .el-form-item) {
		margin-left: 0;
	}
}

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

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

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

	.empty {
		grid-column: 1 / -1;
	}
}

.card {
	overflow: hidden;
	padding: 16px;
	border: 1px solid var(--border-light);
	border-radius: 20px;
	background: var(--bg-base);
	display: flex;
	flex-direction: column;
	gap: 14px;
	box-shadow: var(--shadow-sm);
	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__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);
	line-height: 1.6;
}

.card-info {
	display: flex;
	flex-direction: column;
	gap: 8px;
	padding: 0 4px;
}

.info-row {
	display: flex;
	align-items: center;
	gap: 8px;
	font-size: 13px;
}

.info-label {
	color: var(--text-tertiary);
	flex-shrink: 0;
	min-width: 70px;
}

.info-value {
	color: var(--text-primary);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.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);
}

.pagination {
	display: flex;
	justify-content: flex-end;
	padding-top: 8px;
}

@media (max-width: 960px) {
	.toolbar {
		flex-direction: column;
	}
}
</style>
