<template>
	<div class="ai-wrapper">
		<div class="header">
			<div class="icon">
				<img src="@/assets/icons/aiBox/ai-bg.png" alt="" />
				<div class="inner-icon">
					<img src="@/assets/icons/aiBox/ai-logo.png" alt="" />
				</div>
			</div>
			<div class="title">智能问答</div>
			<div class="close" @click="handleClose">
				<img src="@/assets/icons/aiBox/close.png" alt="" />
			</div>
		</div>
		<div class="main">
			<div class="chat-content" ref="contentContainer">
				<!-- 消息列表 -->
				<div class="message-list">
					<div v-for="(message, index) in messages" :key="index" :class="['message-item', message.type]">
						<!-- AI 消息 -->
						<div v-if="message.type === 'ai'" class="message ai-message">
							<div class="avatar">AI</div>
							<div class="bubble">
								<div class="content markdown-content" v-html="renderMarkdown(message.content)"></div>
							</div>
						</div>

						<!-- 用户消息 -->
						<div v-else class="message user-message">
							<div class="bubble">
								<div class="content">{{ message.content }}</div>
							</div>
							<div class="avatar">我</div>
						</div>
					</div>

					<!-- 加载状态 -->
					<div v-if="isLoading" class="message-item ai">
						<div class="message ai-message">
							<div class="avatar">AI</div>
							<div class="bubble">
								<div class="loading-indicator">
									<span class="dot"></span>
									<span class="dot"></span>
									<span class="dot"></span>
								</div>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>
		<div class="footer">
			<el-input type="textarea" :rows="3" v-model="userInput" placeholder="请输入问题开启智能问答" />
			<div class="btn">
				<div class="icon">
					<img src="@/assets/icons/aiBox/idea.png" alt="" />
				</div>
				<div class="text">概括页面内容</div>
			</div>
			<div class="submit" @click="sendMessage">
				<img src="@/assets/icons/aiBox/submit.png" alt="" />
			</div>
		</div>
	</div>
</template>

<script setup>
import { ref, computed, nextTick, 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 stopGenerate = () => {
	if (abortController.value) {
		abortController.value.abort();
		abortController.value = null;
		isLoading.value = false;
		ElMessage.info("已停止生成");
	}
};

const emit = defineEmits(["close"]);

const handleClose = () => {
	emit("close");
};

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

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

<style lang="scss" scoped>
.ai-wrapper {
	width: 548px;
	height: 1048px;
	box-sizing: border-box;
	border: 1px solid rgba(234, 236, 238, 1);
	border-radius: 10px;
	background: rgba(255, 255, 255, 1);
	.header {
		position: relative;
		display: flex;
		height: 50px;
		border-bottom: 1px solid rgba(234, 236, 238, 1);
		.icon {
			width: 30px;
			height: 28px;
			margin-top: 11px;
			margin-left: 14px;
			position: relative;
			img {
				width: 100%;
				height: 100%;
			}
			.inner-icon {
				position: absolute;
				top: 3px;
				left: 6px;
				width: 15px;
				height: 11px;
				img {
					width: 100%;
					height: 100%;
				}
			}
		}
		.title {
			margin-top: 10px;
			margin-left: 12px;
			height: 30px;
			color: rgba(59, 65, 75, 1);
			font-family: Microsoft YaHei;
			font-size: 16px;
			font-weight: 700;
			line-height: 30px;
		}
		.close {
			position: absolute;
			right: 22px;
			top: 21px;
			width: 12px;
			height: 12px;
			cursor: pointer;
			img {
				width: 100%;
				height: 100%;
			}
		}
	}

	.main {
		height: 830px;
		// background: rgba(225, 225, 225, 0.5);
		width: 520px;
		margin: 10px auto;
		overflow-x: hidden;
		overflow-y: auto;
	}

	.footer {
		position: absolute;
		left: 22px;
		bottom: 20px;
		width: 504px;
		height: 120px;
		box-sizing: border-box;
		border: 1px solid rgba(234, 236, 238, 1);
		border-radius: 10px;
		box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
		background: rgba(255, 255, 255, 1);
		overflow: hidden;
		.btn {
			position: absolute;
			left: 20px;
			bottom: 15px;
			width: 160px;
			height: 36px;
			box-sizing: border-box;
			border: 1px solid rgba(5, 95, 194, 1);
			border-radius: 18px;
			display: flex;
			justify-content: center;
			align-items: center;
			gap: 8px;
			.icon {
				width: 14px;
				height: 14px;
				img {
					width: 100%;
					height: 100%;
				}
			}
			.text {
				height: 30px;
				color: rgba(5, 95, 194, 1);
				font-family: Microsoft YaHei;
				font-size: 16px;
				font-weight: 400;
				line-height: 30px;
			}
		}
		.submit {
			position: absolute;
			right: 19px;
			bottom: 15px;
			width: 36px;
			height: 36px;
			cursor: pointer;
			img {
				width: 100%;
				height: 100%;
			}
		}
	}
}

:deep(.el-textarea__inner) {
	border: none;
	/* 去掉右下角斜线（调整 resize） */
	resize: none;
	/* 去掉焦点边框 */
	outline: none;
	box-shadow: none;

	color: rgba(132, 136, 142, 1);
	font-family: Microsoft YaHei;
	font-size: 16px;
	font-weight: 400;
	line-height: 30px;
}

:deep(.el-textarea__inner::placeholder) {
	color: rgba(132, 136, 142, 1);
	font-family: Microsoft YaHei;
	font-size: 16px;
	font-weight: 400;
	line-height: 30px;
}

/* 确保获得焦点时也没有边框 */
:deep(.el-textarea__inner:focus) {
	border: none;
	outline: none;
	box-shadow: none;
}

/* 确保获得焦点时也没有边框 */
:deep(.el-textarea__inner:hover) {
	border: none;
	outline: none;
	box-shadow: none;
}

/* 对话内容区域 */
.chat-content {
	flex: 1;
	overflow-y: auto;
	padding: 20px;
	background: #fff;
}

.message-list {
	max-width: 900px;
	margin: 0 auto;
}

.message-item {
	margin-bottom: 24px;
}

.message {
	display: flex;
	align-items: flex-start;
	gap: 12px;
	max-width: 100%;
}

.user-message {
	justify-content: flex-end;
}

.ai-message {
	justify-content: flex-start;
}

.avatar {
	width: 40px;
	height: 40px;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 14px;
	font-weight: 600;
	flex-shrink: 0;
}

.user-message .avatar {
	background: #409eff;
	color: white;
	order: 2;
}

.ai-message .avatar {
	background: #8ac4ff;
	color: white;
}

.bubble {
	max-width: 100%;
	padding: 10px 12px;
	border-radius: 12px;
	position: relative;
}

.user-message .bubble {
	background: rgba(231, 243, 255, 1);
	color: white;
	border-radius: 20px 0 20px 20px;
}

.ai-message .bubble {
	background: #f0f2f5;
	color: rgba(59, 65, 75, 1);
	font-family: Microsoft YaHei;
	font-size: 16px;
	font-weight: 400;
	border-radius: 0 20px 20px 20px;
}

.content {
	line-height: 1.6;
	word-wrap: break-word;
}

.user-message .content {
	color: rgba(5, 95, 194, 1);
}

/* Markdown 内容样式 */
.markdown-content :deep(h1) {
	font-size: 1.4em;
	margin: 0.8em 0 0.4em 0;
	font-weight: 600;
}

.markdown-content :deep(h2) {
	font-size: 1.2em;
	margin: 0.8em 0 0.4em 0;
	font-weight: 600;
}

.markdown-content :deep(h3) {
	font-size: 1.1em;
	margin: 0.8em 0 0.4em 0;
	font-weight: 600;
}

.markdown-content :deep(p) {
	margin: 0.4em 0;
}

.markdown-content :deep(code) {
	background: rgba(175, 184, 193, 0.2);
	padding: 0.2em 0.4em;
	border-radius: 3px;
	font-size: 0.9em;
	font-family: "SFMono-Regular", Consolas, monospace;
}

.markdown-content :deep(pre) {
	background: #f6f8fa;
	padding: 12px;
	border-radius: 6px;
	overflow: auto;
	margin: 1em 0;
}

.markdown-content :deep(pre code) {
	background: none;
	padding: 0;
}

.markdown-content :deep(blockquote) {
	border-left: 4px solid #dfe2e5;
	padding-left: 16px;
	margin: 1em 0;
	color: #6a737d;
}

.markdown-content :deep(ul),
.markdown-content :deep(ol) {
	padding-left: 2em;
	margin: 1em 0;
}

/* 加载指示器 */
.loading-indicator {
	display: flex;
	gap: 4px;
	padding: 8px 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;
}

@keyframes bounce {
	0%,
	80%,
	100% {
		transform: scale(0.8);
		opacity: 0.5;
	}
	40% {
		transform: scale(1);
		opacity: 1;
	}
}

/* 滚动条样式 */
.chat-content::-webkit-scrollbar {
	width: 6px;
}

.chat-content::-webkit-scrollbar-track {
	background: #f1f1f1;
}

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

.chat-content::-webkit-scrollbar-thumb:hover {
	background: #a8a8a8;
}
</style>