<template>
	<el-dialog
		v-model="visible"
		title="选择提示词"
		width="900px"
		:close-on-click-modal="false"
		destroy-on-close
		@close="handleClose"
	>
		<div class="prompt-selector-dialog">
			<div class="prompt-header">
				<div class="search-bar">
					<el-input v-model="searchParams.keyword" placeholder="搜索提示词内容" clearable @clear="handleSearch" @keyup.enter="handleSearch">
						<template #prefix>
							<el-icon><Search /></el-icon>
						</template>
					</el-input>
					<el-button type="primary" @click="handleSearch">搜索</el-button>
				</div>
			</div>

			<div class="prompt-content" v-loading="loading">
				<el-empty v-if="!loading && promptList.length === 0" description="暂无提示词数据" :image-size="100" />
				<el-table v-else :data="promptList" height="360" border stripe style="width: 100%" @row-click="handleSelectPrompt">
					<el-table-column label="节点类型" width="120" prop="nodeType" />
					<el-table-column label="提示词内容" prop="prompt" show-overflow-tooltip />
					<el-table-column label="来源" width="80">
						<template #default="{ row }">
							<el-tag :type="row.sourceType === 1 ? 'success' : 'info'" size="small">
								{{ row.sourceType === 1 ? '公共' : '自定义' }}
							</el-tag>
						</template>
					</el-table-column>
					<el-table-column label="选择" width="60" align="center">
						<template #default="{ row }">
							<el-icon v-if="selectedPrompt?.id === row.id" class="check-icon" color="#67c23a">
								<CircleCheck />
							</el-icon>
						</template>
					</el-table-column>
				</el-table>
			</div>

			<div v-if="shouldRenderPagination" class="pagination-panel">
				<div class="pagination-summary">共 {{ displayTotal }} 条</div>
				<el-pagination
					v-model:current-page="pagination.pageNum"
					v-model:page-size="pagination.pageSize"
					:total="displayTotal"
					:page-sizes="[10, 20, 50]"
					layout="sizes, prev, pager, next, jumper"
					background
					:hide-on-single-page="false"
					@current-change="handlePageChange"
					@size-change="handleSizeChange"
				/>
			</div>
		</div>

		<template #footer>
			<el-button @click="handleClose">取消</el-button>
			<el-button type="primary" :disabled="!selectedPrompt" @click="handleConfirm">确定</el-button>
		</template>
	</el-dialog>
</template>

<script setup lang="ts">
import { computed, reactive, ref, watch } from 'vue';
import { Search, CircleCheck } from '@element-plus/icons-vue';
import { getPromptList, type PromptItem } from '/@/api/settings/promptManager';

interface Props {
	modelValue: boolean;
	defaultPrompt?: PromptItem | null;
	nodeType?: string;
}

interface Emits {
	(e: 'update:modelValue', value: boolean): void;
	(e: 'confirm', prompt: PromptItem): void;
}

const props = withDefaults(defineProps<Props>(), {
	modelValue: false,
	defaultPrompt: null,
	nodeType: '',
});

const emit = defineEmits<Emits>();

const visible = ref(false);
const loading = ref(false);
const promptList = ref<PromptItem[]>([]);
const selectedPrompt = ref<PromptItem | null>(null);
const searchParams = reactive({ keyword: '' });
const pagination = reactive({ pageNum: 1, pageSize: 10, total: 0 });

const displayTotal = computed(() => {
	if (pagination.total > 0) return pagination.total;
	if (promptList.value.length > 0) return promptList.value.length;
	return 0;
});

const shouldRenderPagination = computed(() => displayTotal.value > 0);

watch(
	() => props.modelValue,
	(val) => {
		visible.value = val;
		if (val) {
			selectedPrompt.value = props.defaultPrompt || null;
			pagination.pageNum = 1;
			fetchPromptList();
		}
	}
);

watch(
	() => props.nodeType,
	() => {
		if (visible.value) {
			pagination.pageNum = 1;
			fetchPromptList();
		}
	}
);

watch(visible, (val) => {
	if (!val) {
		emit('update:modelValue', false);
	}
});

const resolvePromptList = (payload: any): PromptItem[] => {
	if (Array.isArray(payload?.data?.list)) return payload.data.list;
	if (Array.isArray(payload?.list)) return payload.list;
	if (Array.isArray(payload?.rows)) return payload.rows;
	return [];
};

const resolvePromptTotal = (payload: any, list: PromptItem[]) => {
	const totalCandidates = [payload?.data?.total, payload?.total, payload?.data?.count, payload?.count];
	const validTotal = totalCandidates.find((item) => typeof item === 'number' && !Number.isNaN(item));
	if (typeof validTotal === 'number') return validTotal;
	return list.length;
};

const fetchPromptList = async () => {
	loading.value = true;
	try {
		const params = {
			pageNum: pagination.pageNum,
			pageSize: pagination.pageSize,
			keyword: searchParams.keyword || undefined,
			nodeType: props.nodeType || undefined,
		};
		const res = await getPromptList(params);
		const list = resolvePromptList(res);
		promptList.value = list;
		pagination.total = resolvePromptTotal(res, list);
	} catch (error) {
		promptList.value = [];
		pagination.total = 0;
	} finally {
		loading.value = false;
	}
};

const handleSearch = () => {
	pagination.pageNum = 1;
	fetchPromptList();
};

const handlePageChange = () => {
	fetchPromptList();
};

const handleSizeChange = (size: number) => {
	pagination.pageSize = size;
	pagination.pageNum = 1;
	fetchPromptList();
};

const handleSelectPrompt = (prompt: PromptItem) => {
	selectedPrompt.value = prompt;
};

const handleConfirm = () => {
	if (!selectedPrompt.value) return;
	emit('confirm', selectedPrompt.value);
	handleClose();
};

const handleClose = () => {
	visible.value = false;
	selectedPrompt.value = null;
};
</script>

<style scoped lang="scss">
.prompt-selector-dialog {
	display: flex;
	flex-direction: column;
	gap: 16px;
}

.prompt-header {
	flex-shrink: 0;
}

.search-bar {
	display: flex;
	gap: 12px;
}

.search-bar :deep(.el-input) {
	flex: 1;
}

.prompt-content {
	min-height: 360px;
}

.pagination-panel {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding-top: 8px;
	border-top: 1px solid var(--el-border-color-lighter);
}

.pagination-summary {
	font-size: 14px;
	color: var(--el-text-color-regular);
	white-space: nowrap;
}

.pagination-panel :deep(.el-pagination) {
	margin-left: auto;
}
</style>
