<template>
	<div class="wrapper">
		<div class="header">
			<!-- <span>首页 </span>> <span>综合检索 </span>> <span>智能问答 </span> -->
			<div class="header-item">首页</div>
			<div class="header-item">></div>
			<div class="header-item back-item" @click="handleBackHome">综合检索</div>
			<div class="header-item">></div>
			<div class="header-item">智能问答</div>
		</div>
		<div class="main">
			<div class="left">
				<div class="left-header">
					<div class="icon">
						<img src="./assets/images/ai.png" alt="" />
					</div>
					<el-input placeholder="新对话" v-model="newChatTitle" style="width: 220px" />
				</div>
				<div class="left-main">
					<div class="left-main-title">{{ "历史对话" }}</div>
					<div class="left-list">
						<div
							class="left-list-item"
							:class="{ itemActive: currentChatId === item.id }"
							v-for="(item, index) in chatList"
							:key="index"
						>
							{{ item.title }}
						</div>
					</div>
				</div>
			</div>
			<div class="right">
				<div class="right-header">{{ curChatTitle }}</div>
				<div class="right-main">
					<div class="right-main-content">
						<div class="chat-content" ref="contentContainer">
							<!-- 消息列表 -->
							<div class="message-list">
								<div v-for="(message, index) in messages" :key="index">
									<!-- AI 消息 -->
									<div v-if="message.type === 'ai'" class="ai-item">
										<div class="ai-header">
											<div class="icon">
												<img src="./assets/images/ai-avator.png" alt="" />
											</div>
											<div class="text">{{ `已深度思考` }}</div>
										</div>
										<div v-if="message.think" class="think-title">思考内容</div>
										<div
											v-if="message.think"
											class="content think-content"
											v-html="renderMarkdown(message.think)"
										></div>
										<div v-if="message.content" class="answer-title">正文内容</div>
										<div
											v-if="message.content"
											class="content ai-content"
											v-html="renderMarkdown(message.content)"
										></div>
									</div>
									<!-- 用户消息 -->
									<div v-else class="user-item">
										<div class="user-bubble">
											<div class="user-content">{{ message.content }}</div>
										</div>
									</div>
								</div>

								<!-- 加载状态 -->
								<div v-if="isLoading" class="ai-item">
									<div class="ai-header">
										<div class="icon">
											<img src="./assets/images/ai-avator.png" alt="" />
										</div>
										<div class="text">{{ `正在思考中，请稍候` }}</div>
									</div>
									<div class="loading-indicator">
										<span class="dot"></span>
										<span class="dot"></span>
										<span class="dot"></span>
									</div>
								</div>
							</div>
						</div>
					</div>
					<div class="right-main-footer">
						<el-input @keyup.enter="sendMessage" type="textarea" placeholder="发送消息" :rows="4" v-model="userInput" />
						<div class="input-footer">
							<div class="icon1">
								<el-tooltip effect="dark" content="录音" placement="top">
									<img src="./assets/images/microphone.png" alt="" />
								</el-tooltip>
							</div>
							<div class="icon2">
								<el-tooltip effect="dark" content="收藏" placement="top">
									<img src="./assets/images/attach.png" alt="" />
								</el-tooltip>
							</div>
							<div class="line"></div>
							<div class="submit" @click="sendMessage">
								<el-tooltip effect="dark" content="发送" placement="top">
									<img src="./assets/images/submit.png" alt="" />
								</el-tooltip>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>
	</div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, nextTick } from "vue";
import { fetchEventSource } from "@microsoft/fetch-event-source";
import MarkdownIt from "markdown-it";
import { ElMessage } from "element-plus";
import { getChat } from "@/api/chat";
import router from "@/router/index";
import json5 from "json5";

// 返回综合检索
const handleBackHome = () => {
	router.push({
		path: "/comprehensiveSearch"
	});
};

const contentContainer = ref(null);

const userInput = ref("");
const isLoading = ref(false);
const abortController = ref(null);

// 消息数据
const messages = ref([
	{
		type: "user",
		content: "你好"
	},
	{
		type: "ai",
		content: "您好！我是AI助手，有什么可以帮助您的吗？"
	}
]);

// Markdown 渲染器
const md = new MarkdownIt();

// 渲染 markdown
const renderMarkdown = content => {
	return md.render(content);
};

// 自动滚动到底部
const scrollToBottom = async () => {
	await nextTick();
	if (contentContainer.value) {
		const container = contentContainer.value;
		container.scrollTop = container.scrollHeight;
	}
};

// 添加消息
const addMessage = (type, content) => {
	messages.value.push({
		type,
		content,
		timestamp: new Date().getTime()
	});
	scrollToBottom();
};

// 更新最后一条 AI 消息（用于流式输出）
const updateLastAIMessage = content => {
	const lastMessage = messages.value[messages.value.length - 1];
	if (lastMessage && lastMessage.type === "ai") {
		if (isCurAnswerMessage.value) {
			lastMessage.content = content;
		} else {
			lastMessage.think = content;
		}

		scrollToBottom();
	}
};

let aiMessage = ref("");

const isCurAnswerMessage = ref(false);

function parseOuterOnly(json5String, maxDepth = 1) {
	let currentDepth = 0;

	return json5.parse(json5String, (key, value) => {
		// 检查当前深度
		if (currentDepth > maxDepth) {
			return value; // 超过最大深度，直接返回值
		}

		// 如果是对象或数组，增加深度计数
		if (typeof value === "object" && value !== null) {
			currentDepth++;
		}

		return value;
	});
}

// 使用 fetchEventSource 连接
const connectSSE = async question => {
	// 添加用户消息
	addMessage("user", question);

	// 添加空的 AI 消息用于流式更新
	addMessage("ai", "");

	isLoading.value = true;

	// 创建 AbortController 用于取消请求
	abortController.value = new AbortController();

	const params = {
		// question: "川普1期对华制裁领域分布情况"
		question: question
		// knowledge_base_name: "kb_test251112",
		// top_k: 6,
		// score_threshold: 0.5,
		// metadata: { year: 2024 }
	};

	fetchEventSource("/sseChat/rag/chat/stream", {
		method: "POST",
		headers: {
			"Content-Type": "application/json"
		},
		body: JSON.stringify(params),
		signal: abortController.value.signal,
		openWhenHidden: true,
		async onopen(res) {
			isLoading.value = false;
			console.log("流式回答开始", res);
		},
		async onmessage(res) {
			console.log("res", res);
			let msgData = parseOuterOnly(res.data);
			if (res.event === "end_of_workflow") {
				ElMessage.success("问答完成！");
				abortController.value.abort();
				abortController.value = new AbortController();
				return;
			}
			if (res.event === "start_of_agent" && msgData.agent_name === "answer") {
				isCurAnswerMessage.value = true;
				aiMessage.value = "";
			}
			if (res.event === "message") {
				let content = msgData.delta.content;
				console.log("msgData", msgData);
				console.log("content", content);
				if (content !== "[DONE]") {
					aiMessage.value += content;
					updateLastAIMessage(aiMessage.value);
				} else {
					aiMessage.value = "";
					abortController.value.abort();
					abortController.value = new AbortController();
				}
			}
		},
		onerror(error) {
			ElMessage({
				message: "问答报错!",
				type: "warning"
			});
			abortController.value.abort();
			abortController.value = new AbortController();
			throw new Error(error);
		}
	}).catch(error => {
		ElMessage({
			message: "问答报错!",
			type: "warning"
		});
		abortController.value.abort();
		abortController.value = new AbortController();
		throw new Error(error);
	});
};

const chat = async () => {
	const params = {
		query: "如何检索？",
		knowledge_base_name: "kb_test251112",
		top_k: 6,
		score_threshold: 0.5,
		metadata: { year: 2024 }
	};

	try {
		const res = await getChat(params);
		console.log("chat", res);
	} catch (error) {
		console.error(error);
	}
};

// 发送消息
const sendMessage = async () => {
	const question = userInput.value.trim();
	if (!question) {
		ElMessage.warning("请输入问题");
		return;
	}

	if (isLoading.value) {
		ElMessage.warning("请等待上一条消息回复完成");
		return;
	}

	userInput.value = "";
	await connectSSE(question);
	// chat();
};

const newChatTitle = ref(""); // 新对话
const curChatTitle = ref("美国对中国制裁实体清单");
const currentChatId = ref(1);
const chatList = ref([
	{
		id: 1,
		title: "美国对中国制裁实体清单"
	},
	{
		id: 2,
		title: "制作中国进口依赖度柱状图"
	},
	{
		id: 3,
		title: "列举2025年科技产品"
	},
	{
		id: 4,
		title: "获取美国国会议员名单"
	},
	{
		id: 5,
		title: "2000年以后美国金融法案列举"
	},
	{
		id: 6,
		title: "科研机构及高校仪器进口排名"
	}
]);

onMounted(() => {
	scrollToBottom();
});

onUnmounted(() => {
	if (abortController.value) {
		abortController.value.abort();
	}
});
</script>

<style lang="scss" scoped>
:deep(.el-input__wrapper) {
	box-shadow: none;
}
:deep(.el-input__wrapper:hover) {
	box-shadow: none !important;
}

:deep(.el-input__wrapper.is-focus) {
	box-shadow: none !important;
}
:deep(.el-input ::placeholder) {
	color: var(--color-main-active);
	font-family: Microsoft YaHei;
	font-size: 16px;
	font-weight: 400;
}
:deep(.el-input__inner) {
	color: #333;
	font-family: Microsoft YaHei;
	font-size: 16px;
	font-weight: 400;
}

:deep(.el-textarea__inner) {
	box-shadow: none;
	border-radius: 20px;
	resize: none;
}
:deep(.el-textarea__inner:hover) {
	box-shadow: none !important;
}

:deep(.el-textarea__inner.is-focus) {
	box-shadow: none !important;
}
:deep(.el-textarea ::placeholder) {
	color: rgba(132, 136, 142, 1);
	font-family: Microsoft YaHei;
	font-size: 16px;
	font-weight: 400;
}
:deep(.el-textarea__inner) {
	color: #333;
	font-family: Microsoft YaHei;
	font-size: 16px;
	font-weight: 400;
}
.wrapper {
	.header {
		height: 64px;
		color: #fff;
		font-family: Microsoft YaHei;
		font-size: 20px;
		font-weight: 700;
		line-height: 26px;
		line-height: 64px;
		background: url("../assets/images/header-bg.png");
		box-sizing: border-box;
		padding-left: 160px;
		display: flex;
		.header-item {
			margin: 0 3px;
		}
		.back-item {
			cursor: pointer;
			&:hover {
				color: #ccc;
			}
		}
	}
	.main {
		margin-top: 16px;
		display: flex;
		justify-content: center;
		gap: 16px;
		.left {
			width: 300px;
			height: 880px;
			border-radius: 4px;
			box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
			background: rgba(255, 255, 255, 1);
			.left-header {
				width: 268px;
				height: 48px;
				margin: 16px auto;
				box-sizing: border-box;
				border: 1px solid rgba(5, 95, 194, 1);
				border-radius: 8px;
				box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
				background: rgba(255, 255, 255, 1);
				display: flex;
				.icon {
					width: 20px;
					height: 13px;
					margin-top: 13px;
					margin-left: 16px;
					img {
						width: 100%;
						height: 100%;
					}
				}
			}
			.left-main {
				margin-top: 24px;
				.left-main-title {
					margin-left: 29px;
					width: 64px;
					height: 24px;
					color: rgba(132, 136, 142, 1);
					font-family: Microsoft YaHei;
					font-size: 16px;
					font-weight: 400;
					line-height: 24px;
					letter-spacing: 0px;
					text-align: left;
				}
				.left-list {
					margin-top: 12px;
					margin-left: 16px;
					width: 268px;
					height: 720px;
					.left-list-item {
						width: 268px;
						height: 48px;
						border-radius: 8px;
						color: rgba(59, 65, 75, 1);
						font-family: Microsoft YaHei;
						font-size: 16px;
						font-weight: 400;
						line-height: 48px;
						box-sizing: border-box;
						padding: 0 12px;
						overflow: hidden;
						text-overflow: ellipsis;
						white-space: nowrap;
						cursor: pointer;
						&:hover {
							background: rgba(246, 250, 255, 1);
						}
					}
					.itemActive {
						background: rgba(246, 250, 255, 1);
						color: var(--color-main-active);
						font-weight: 700;
					}
				}
			}
		}
		.right {
			width: 1284px;
			height: 880px;
			border-radius: 4px;
			box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
			background: rgba(255, 255, 255, 1);
			.right-header {
				height: 64px;
				border-bottom: 1px solid rgba(234, 236, 238, 1);
				line-height: 64px;
				box-sizing: border-box;
				padding-left: 24px;
				color: rgba(59, 65, 75, 1);
				font-family: Microsoft YaHei;
				font-size: 18px;
				font-weight: 700;
			}
			.right-main {
				.right-main-content {
					width: 926px;
					margin-left: 166px;
					height: 630px;
				}
				.right-main-footer {
					margin: 10px auto;
					width: 900px;
					height: 160px;
					box-sizing: border-box;
					border: 1px solid rgba(230, 231, 232, 1);
					border-radius: 20px;
					background: rgba(255, 255, 255, 1);
					.input-footer {
						display: flex;
						justify-content: flex-end;
						.icon1 {
							margin-top: 15px;
							width: 24px;
							height: 24px;
							margin-right: 20px;
							cursor: pointer;
							img {
								width: 100%;
								height: 100%;
							}
						}
						.icon2 {
							margin-top: 15px;
							width: 24px;
							height: 24px;
							margin-right: 20px;
							cursor: pointer;
							img {
								width: 100%;
								height: 100%;
							}
						}
						.line {
							margin-top: 15px;
							margin-right: 20px;
							width: 1px;
							height: 24px;
							background: rgba(234, 236, 238, 1);
						}
						.submit {
							margin-top: 7px;
							margin-right: 12px;
							width: 40px;
							height: 40px;
							border-radius: 20px;
							background: #b4cfed;
							cursor: pointer;
							&:hover {
								background: rgba(5, 95, 194, 1);
							}
							img {
								width: 24px;
								height: 24px;
								margin: 8px;
							}
						}
					}
				}
			}
		}
	}
}

/* 对话内容区域 */
.chat-content {
	overflow-x: hidden;
	overflow-y: auto;
	// padding: 20px;
	background: #fff;
	width: 1118px;
	padding-right: 192px;
	box-sizing: border-box;
	height: 620px;
	.chat-content::-webkit-scrollbar {
		width: 30px;
	}

	.chat-content::-webkit-scrollbar-thumb {
		background: #000;
		border-radius: 3px;
	}

	.chat-content::-webkit-scrollbar-thumb:hover {
		background: #555;
	}

	.message-list {
		padding-bottom: 20px;
	}
	.ai-item {
		width: 926px;
		overflow: hidden;
		.ai-header {
			height: 22px;
			display: flex;
			.icon {
				width: 10px;
				height: 10px;
				img {
					width: 100%;
					height: 100%;
				}
			}
			.text {
				margin-left: 16px;
				height: 22px;
				color: rgba(132, 136, 142, 1);
				font-family: Microsoft YaHei;
				font-size: 14px;
				font-weight: 400;
				line-height: 22px;
				letter-spacing: 0px;
				text-align: left;
			}
		}
		.think-title {
			margin-left: 26px;
			height: 22px;
			color: rgba(132, 136, 142, 1);
			font-family: Microsoft YaHei;
			font-size: 14px;
			font-weight: 400;
			line-height: 22px;
			letter-spacing: 0px;
			text-align: left;
		}
		.answer-title {
			margin-top: 10px;
			margin-left: 26px;
			height: 22px;
			color: var(--color-main-active);
			font-family: Microsoft YaHei;
			font-size: 18px;
			font-weight: 700;
			line-height: 24px;
			letter-spacing: 0px;
			text-align: left;
		}
		.think-content {
			background: rgba(245, 245, 245, 0.5);
			width: 900px;
			margin-left: 26px;
			padding: 1px 10px;
			border-radius: 5px;
		}
		.ai-content {
			margin-top: 10px;
			width: 900px;
			margin-left: 26px;
			background: rgba(246, 250, 255, 1);
			padding: 1px 10px;
			border-radius: 5px;
		}
	}
	.user-item {
		margin-top: 32px;
		height: 42px;
		display: flex;
		justify-content: flex-end;
		.user-bubble {
			line-height: 42px;
			border-radius: 21px 0px 21px 21px;
			background: rgba(234, 236, 238, 1);
			box-sizing: border-box;
			padding: 0 20px;
			text-align: right;
			word-wrap: break-word;
			.user-content {
				color: rgba(59, 65, 75, 1);
				font-family: Microsoft YaHei;
				font-size: 16px;
				font-weight: 400;
				line-height: 42px;
				letter-spacing: 0px;
				text-align: left;
			}
		}
	}
}

/* 加载指示器 */
.loading-indicator {
	margin-left: 26px;
	height: 30px;
	display: flex;
	gap: 4px;
	padding: 11px 0;
}

.dot {
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background: #999;
	animation: bounce 1.4s infinite ease-in-out;
}

.dot:nth-child(1) {
	animation-delay: -0.32s;
}
.dot:nth-child(2) {
	animation-delay: -0.16s;
}
</style>