<template>
	<div class="wrapper">
		<div class="header"><span>首页 </span>> <span>综合检索 </span>> <span>智能问答 </span></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">{{ `已深度思考（用时6秒钟）` }}</div>
										</div>
										<div 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 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 } from "vue";
import { fetchEventSource } from "@microsoft/fetch-event-source";
import MarkdownIt from "markdown-it";
import { ElMessage } from "element-plus";
import { getChat } from "@/api/chat";

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") {
		lastMessage.content = content;
		scrollToBottom();
	}
};

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

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

	isLoading.value = true;

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

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

	try {
		await fetchEventSource("/chat/knowledge_base/search_docs", {
			method: "POST",
			headers: {
				"Content-Type": "application/json"
			},
			body: JSON.stringify(params),
			signal: abortController.value.signal,
			onopen: async response => {
				console.log("SSE 连接已建立", response.status);
				if (response.status !== 200) {
					throw new Error(`请求失败: ${response.status}`);
				}
			},

			onmessage: event => {
				try {
					if (event.data === "[DONE]") {
						// 流式输出结束
						isLoading.value = false;
						return;
					}

					const data = JSON.parse(event.data);

					if (data.type === "content" && data.content) {
						// 流式更新内容
						updateLastAIMessage(prev => prev + data.content);
					} else if (data.type === "error") {
						throw new Error(data.message || "请求失败");
					}
				} catch (error) {
					console.error("解析 SSE 数据错误:", error);
				}
			},

			onclose: () => {
				console.log("SSE 连接已关闭");
				isLoading.value = false;
			},

			onerror: error => {
				console.error("SSE 连接错误:", error);
				ElMessage.error("连接失败，请重试");
				isLoading.value = false;
				// 不要抛出错误，否则会重试
			}
		});
	} catch (error) {
		console.error("SSE 请求失败:", error);
		if (error.name !== "AbortError") {
			ElMessage.error(error.message || "请求失败");
		}
		isLoading.value = false;
	}
};

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;
	}
	.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-y: auto;
	// padding: 20px;
	background: #fff;
	width: 926px;
	.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;
			}
		}
		.ai-content {
			margin-top: 10px;
			width: 900px;
			margin-left: 26px;
		}
	}
	.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>