<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>
					<el-button type="primary" plain @click="handleCreate">
						<el-icon><Plus /></el-icon>
						新增提示词
					</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 ? '管理员' : row.sourceType === 2 ? '用户' : row.sourceType }}
							</el-tag>
						</template>
					</el-table-column>
					<el-table-column label="操作" width="120" align="center" fixed="right">
						<template #default="{ row }">
							<template v-if="canManagePrompt(row)">
								<el-button type="primary" link size="small" @click.stop="handleEdit(row)">编辑</el-button>
								<el-button type="danger" link size="small" @click.stop="handleDeleteConfirm(row)">删除</el-button>
							</template>
							<span v-else class="operation-placeholder">-</span>
						</template>
					</el-table-column>
					<el-table-column label="选择" width="60" align="center" fixed="right">
						<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" :loading="confirmLoading" @click="handleConfirm">确定</el-button>
		</template>
	</el-dialog>

	<el-dialog
		v-model="showFormDialog"
		:title="isEdit ? '编辑提示词' : '新增提示词'"
		width="600px"
		:close-on-click-modal="false"
		destroy-on-close
		@close="resetFormState"
	>
		<el-form :model="formState" label-width="100px">
			<el-form-item label="节点类型" required>
				<el-select v-model="formState.nodeType" placeholder="请选择节点类型" class="w100" clearable :disabled="Boolean(props.nodeType)" v-loading="nodeLibraryLoading">
					<el-option v-for="option in nodeOptions" :key="option.value" :label="option.label" :value="option.value" />
				</el-select>
			</el-form-item>
			<el-form-item label="提示词内容" required>
				<el-input v-model="formState.prompt" type="textarea" :rows="8" placeholder="请输入提示词内容" clearable />
			</el-form-item>
		</el-form>
		<template #footer>
			<el-button @click="showFormDialog = false">取消</el-button>
			<el-button type="primary" :loading="submitLoading" @click="handleSubmit">
				{{ isEdit ? '保存修改' : '确定' }}
			</el-button>
		</template>
	</el-dialog>

	<el-dialog v-model="showDeleteDialog" title="确认删除" width="400px" :close-on-click-modal="false" destroy-on-close>
		<div>确定要删除这个提示词吗？</div>
		<template #footer>
			<el-button @click="showDeleteDialog = false">取消</el-button>
			<el-button type="primary" :loading="deleteLoading" @click="handleDelete">确定</el-button>
		</template>
	</el-dialog>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from 'vue';
import { Search, CircleCheck, Plus } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
import {
	checkIsSuperAdmin,
	createPrompt,
	deletePrompt,
	getNodeLibraryList,
	getPromptList,
	updatePrompt,
	type CreatePromptResponse,
	type NodeLibraryGroup,
	type NodeLibraryNode,
	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 nodeLibraryLoading = ref(false);
const submitLoading = ref(false);
const deleteLoading = ref(false);
const confirmLoading = ref(false);
const showFormDialog = ref(false);
const showDeleteDialog = ref(false);
const isEdit = ref(false);
const editId = ref<number | string | null>(null);
const deleteId = ref<number | string | null>(null);
const promptList = ref<PromptItem[]>([]);
const selectedPrompt = ref<PromptItem | null>(null);
const nodeLibraryGroups = ref<NodeLibraryGroup[]>([]);
const searchParams = reactive({ keyword: '' });
const pagination = reactive({ pageNum: 1, pageSize: 10, total: 0 });
const formState = reactive({
	nodeType: '',
	prompt: '',
	sourceType: 2,
});

const nodeOptions = computed(() => {
	const options: Array<{ label: string; value: string }> = [];
	nodeLibraryGroups.value.forEach((group: NodeLibraryGroup) => {
		group.items.forEach((item: NodeLibraryNode) => {
			if (!item.promptOption) return;
			options.push({
				label: item.nodeName,
				value: item.nodeCode,
			});
		});
	});
	return options;
});

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();
			loadNodeLibrary();
		}
	}
);

watch(
	() => props.nodeType,
	() => {
		if (visible.value) {
			pagination.pageNum = 1;
			fetchPromptList();
		}
		if (!showFormDialog.value) {
			formState.nodeType = props.nodeType || '';
		}
	}
);

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

const canManagePrompt = (prompt: PromptItem) => Number(prompt?.sourceType) === 2;

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 resolveNodeLibraryGroups = (payload: any): NodeLibraryGroup[] => {
	if (Array.isArray(payload?.data?.groups)) return payload.data.groups;
	if (Array.isArray(payload?.groups)) return payload.groups;
	return [];
};

const resolveIsSuperAdmin = (payload: any) => {
	if (typeof payload?.data?.isSuperAdmin === 'boolean') return payload.data.isSuperAdmin;
	if (typeof payload?.isSuperAdmin === 'boolean') return payload.isSuperAdmin;
	return false;
};

const resolveCreatedPrompt = (payload: any, fallback: PromptItem): PromptItem => {
	const created = (payload?.data || payload) as CreatePromptResponse | undefined;
	return {
		id: created?.id ?? fallback.id,
		tenantId: created?.tenantId,
		creator: created?.creator,
		createdAt: created?.createdAt,
		updater: created?.updater,
		updatedAt: created?.updatedAt,
		deletedAt: created?.deletedAt ?? null,
		nodeType: created?.nodeType || fallback.nodeType,
		prompt: created?.prompt || fallback.prompt,
		sourceType: Number(created?.sourceType ?? 2),
	};
};

const loadNodeLibrary = async () => {
	if (nodeLibraryGroups.value.length > 0) return;
	nodeLibraryLoading.value = true;
	try {
		const res = await getNodeLibraryList();
		nodeLibraryGroups.value = resolveNodeLibraryGroups(res);
	} catch (error) {
		ElMessage.error('加载节点类型失败');
	} finally {
		nodeLibraryLoading.value = false;
	}
};

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);
		if (selectedPrompt.value?.id) {
			selectedPrompt.value = list.find((item) => item.id === selectedPrompt.value?.id) || selectedPrompt.value;
		}
	} catch (error) {
		promptList.value = [];
		pagination.total = 0;
	} finally {
		loading.value = false;
	}
};

const resetFormState = () => {
	isEdit.value = false;
	editId.value = null;
	formState.nodeType = props.nodeType || '';
	formState.prompt = '';
	formState.sourceType = 2;
};

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 handleCreate = async () => {
	await loadNodeLibrary();
	resetFormState();
	showFormDialog.value = true;
};

const handleEdit = async (prompt: PromptItem) => {
	if (!canManagePrompt(prompt)) return;
	await loadNodeLibrary();
	isEdit.value = true;
	editId.value = prompt.id;
	formState.nodeType = prompt.nodeType || props.nodeType || '';
	formState.prompt = prompt.prompt || '';
	formState.sourceType = Number(prompt.sourceType ?? 0);
	showFormDialog.value = true;
};

const handleSubmit = async () => {
	if (!formState.nodeType?.trim()) {
		ElMessage.warning('请选择节点类型');
		return;
	}
	if (!formState.prompt?.trim()) {
		ElMessage.warning('请输入提示词内容');
		return;
	}

	submitLoading.value = true;
	try {
		const payload = {
			nodeType: formState.nodeType.trim(),
			prompt: formState.prompt.trim(),
			sourceType: formState.sourceType,
		};

		if (isEdit.value && editId.value !== null) {
			await updatePrompt({
				id: editId.value,
				...payload,
			});
			ElMessage.success('修改成功');
		} else {
			await createPrompt(payload);
			ElMessage.success('创建成功');
		}

		showFormDialog.value = false;
		resetFormState();
		pagination.pageNum = 1;
		await fetchPromptList();
	} catch (error) {
		ElMessage.error(isEdit.value ? '修改失败' : '创建失败');
	} finally {
		submitLoading.value = false;
	}
};

const handleDeleteConfirm = (prompt: PromptItem) => {
	if (!canManagePrompt(prompt)) return;
	deleteId.value = prompt.id;
	showDeleteDialog.value = true;
};

const handleDelete = async () => {
	if (deleteId.value === null) return;
	deleteLoading.value = true;
	try {
		await deletePrompt(deleteId.value);
		ElMessage.success('删除成功');
		showDeleteDialog.value = false;
		if (selectedPrompt.value?.id === deleteId.value) {
			selectedPrompt.value = null;
		}
		if (promptList.value.length === 1 && pagination.pageNum > 1) {
			pagination.pageNum -= 1;
		}
		await fetchPromptList();
	} catch (error) {
		ElMessage.error('删除失败');
	} finally {
		deleteLoading.value = false;
		deleteId.value = null;
	}
};

const handleConfirm = async () => {
	if (!selectedPrompt.value) return;

	confirmLoading.value = true;
	try {
		let finalPrompt = selectedPrompt.value;
		const isAdminPrompt = Number(finalPrompt.sourceType) === 1;

		if (isAdminPrompt) {
			const roleRes = await checkIsSuperAdmin();
			const isSuperAdmin = resolveIsSuperAdmin(roleRes);
			if (!isSuperAdmin) {
				const createRes = await createPrompt({
					nodeType: finalPrompt.nodeType,
					prompt: finalPrompt.prompt,
					sourceType: 2,
				});
				finalPrompt = resolveCreatedPrompt(createRes, {
					...finalPrompt,
					id: `copied-${finalPrompt.id}`,
					sourceType: 2,
				});
				selectedPrompt.value = finalPrompt;
				ElMessage.success('已复制为你的用户提示词');
				await fetchPromptList();
			}
		}

		emit('confirm', finalPrompt);
		handleClose();
	} catch (error) {
		ElMessage.error('选择提示词失败');
	} finally {
		confirmLoading.value = false;
	}
};

const handleClose = () => {
	visible.value = false;
	selectedPrompt.value = null;
	showFormDialog.value = false;
	showDeleteDialog.value = false;
	resetFormState();
	deleteId.value = null;
};

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

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

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

.w100 {
	width: 100%;
}
</style>
