<template>
	<el-drawer v-model="visible" :title="'流程运行' + id" :size="800" @close="$emit('close')" class="execution-drawer">
		<!-- 添加标签页切换 -->
		<div class="tab-container">
			<div v-if="hasStartParams" class="tab-item" :class="{ active: activeTab === 'run' }" @click="activeTab = 'run'">调试</div>
			<div class="tab-item" :class="{ active: activeTab === 'result' }" @click="activeTab = 'result'">结果</div>
			<div class="tab-item" :class="{ active: activeTab === 'trace' }" @click="activeTab = 'trace'">追踪</div>
		</div>

		<div class="p-2.5 h-[calc(100vh-100px)] overflow-y-auto">
			<!-- 添加运行选项卡内容 -->
			<div v-show="activeTab === 'run'">
				<div class="p-4 flex flex-col h-[calc(100vh-150px)]">
					<div class="flex justify-between items-center mb-2">
						<h3 class="text-base font-medium text-gray-700">AI对话</h3>
						
						<div class="flex">
							<!-- 流式调用开关 -->
						<div class="flex items-center">
							<span class="text-sm text-gray-600 mr-2">流式:</span>
							<el-switch
								v-model="chat.isStream"
								class="mr-4"
							/>
						</div>
							<el-button link type="primary" class="flex text-gray-500 hover:text-blue-500" @click="chat.showParams = !chat.showParams">
								<i class="mr-1 text-lg i-tabler-settings"></i>
								<span class="text-sm">{{ chat.showParams ? '隐藏设置' : '显示设置' }}</span>
							</el-button>
							<el-button link type="danger" class="flex text-gray-500 hover:text-red-500" @click="handleClear">
								<i class="mr-1 text-lg i-tabler-trash"></i>
								<span class="text-sm">清空</span>
							</el-button>
						</div>
					</div>

					<el-collapse-transition>
						<div v-if="chat.showParams" class="p-4 mb-4 bg-gray-50 rounded-lg border border-gray-200">
							<el-form label-position="top" require-asterisk-position="right" :model="form">
								<el-row :gutter="20">
									<el-col :span="12">
										<el-form-item label="对话字段" required>
											<el-select v-model="chat.contentId" placeholder="请选择对话字段" class="w-full">
												<el-option v-for="item in startParamsForChat" :key="item.value" :label="item.name" :value="item.type" />
											</el-select>
										</el-form-item>
									</el-col>
								</el-row>

								<!-- 只有选择了对话字段后才显示其他字段 -->
								<template v-if="chat.contentId">
									<div v-for="(row, rowIndex) in groupedParams" :key="'row-' + rowIndex">
										<el-row :gutter="20">
											<el-col v-for="(param, colIndex) in row" :key="'param-' + rowIndex + '-' + colIndex" :span="12">
												<el-form-item :label="param.name" :required="param.required">
													<upload-img v-model:imageUrl="param.value" v-if="param.inputType === 'image'">
														<template #empty>
															<el-icon><Avatar /></el-icon>
															<span>请上传图片</span>
														</template>
													</upload-img>

													<el-input v-if="param.inputType === 'input'" v-model="param.value" :placeholder="'请输入' + param.name" />
													<el-input-number
														v-else-if="param.inputType === 'number'"
														v-model.number="param.value"
														:placeholder="'请输入' + param.name"
														class="w-full"
													/>
													<el-input
														v-else-if="param.inputType === 'textarea'"
														v-model="param.value"
														:placeholder="'请输入' + param.name"
														type="textarea"
														:rows="3"
													/>
													<el-select
														v-else-if="param.inputType === 'select'"
														v-model="param.value"
														:placeholder="'请选择' + param.name"
														class="w-full"
													>
														<el-option v-for="option in param.options" :key="option.value" :label="option.label" :value="option.value" />
													</el-select>
													<div class="mt-1 text-xs text-red-500" v-if="showError && param.required && !param.value">
														请{{
															param.inputType === 'input'
																? '输入'
																: param.inputType === 'textarea'
																? '填写'
																: param.inputType === 'select'
																? '选择'
																: '填写'
														}}{{ param.name }}
													</div>
												</el-form-item>
											</el-col>
										</el-row>
									</div>
								</template>
							</el-form>
						</div>
					</el-collapse-transition>

					<!-- 聊天消息区域 -->
					<el-scrollbar
						ref="chatScrollbarRef"
						height="calc(100% - 50px)"
						class="overflow-y-auto flex-1 mb-4 bg-gray-50 rounded-lg border"
						@scroll="handleScroll"
					>
						<div class="p-4 space-y-4" ref="chatContentRef" @wheel="handleWheel">
							<!-- 系统欢迎消息 -->
							<div class="flex items-start" v-if="chatMessages.length === 0">
								<div
									class="flex flex-shrink-0 justify-center items-center mr-3 w-10 h-10 text-white bg-gradient-to-br from-blue-400 to-blue-600 rounded-full shadow-sm"
								>
									<i class="text-lg i-tabler-robot"></i>
								</div>
								<div class="flex-1 p-4 bg-white rounded-lg border border-gray-100 shadow-sm">
									<p class="text-gray-800">开始新的对话，请在下方输入您的问题。</p>
								</div>
							</div>

							<!-- 聊天消息列表 -->
							<div v-for="(message, index) in chatMessages" :key="index" class="transition-all duration-300">
								<!-- 用户消息 -->
								<div class="flex justify-end items-start mb-4 animate-slideInRight" v-if="message.role === 'user'">
									<div class="flex-1 p-4 mr-3 bg-gradient-to-r from-blue-500 to-blue-600 text-white rounded-lg shadow-sm max-w-[80%]">
										<p>{{ message.content }}</p>
									</div>
									<div class="flex flex-shrink-0 justify-center items-center w-10 h-10 bg-gray-200 rounded-full shadow-sm">
										<i class="text-lg text-gray-600 i-tabler-user">YOU</i>
									</div>
								</div>

								<!-- AI消息 -->
								<div class="flex items-start mb-4 animate-slideInLeft" v-else>
									<div
										class="flex flex-shrink-0 justify-center items-center mr-3 w-10 h-10 text-white bg-gradient-to-br from-blue-400 to-blue-600 rounded-full shadow-sm"
									>
										<i class="text-lg i-tabler-robot">AI</i>
									</div>
									<div class="flex-1 p-4 bg-white rounded-lg shadow-sm border border-gray-100 max-w-[80%]">
										<MdRenderer
											v-if="message.content"
											:source="message.content || ''"
											class="w-full max-w-none prose prose-sm"
											@rendered="() => scrollToBottom(false)"
										/>
										<!-- 流式传输指示器 -->
										<div v-if="message.isStreaming && index === streamingMessageIndex" class="flex items-center mt-2">
											<div class="flex space-x-1">
												<div class="w-2 h-2 bg-blue-400 rounded-full animate-bounce"></div>
												<div class="w-2 h-2 bg-blue-400 rounded-full animate-bounce" style="animation-delay: 0.2s"></div>
												<div class="w-2 h-2 bg-blue-400 rounded-full animate-bounce" style="animation-delay: 0.4s"></div>
											</div>
											<span class="ml-2 text-xs text-gray-400">正在生成中...</span>
										</div>
									</div>
								</div>
							</div>

							<!-- 加载中状态 - 只在没有流式消息占位符时显示 -->
							<div class="flex items-start animate-fadeIn" v-if="isLoading && streamingMessageIndex === -1">
								<div
									class="flex flex-shrink-0 justify-center items-center mr-3 w-10 h-10 text-white bg-gradient-to-br from-blue-400 to-blue-600 rounded-full shadow-sm"
								>
									<i class="text-lg i-tabler-robot"></i>
								</div>
								<div class="flex-1 p-4 bg-white rounded-lg border border-gray-100 shadow-sm">
									<div class="flex space-x-2">
										<div class="w-2 h-2 bg-blue-400 rounded-full animate-bounce"></div>
										<div class="w-2 h-2 bg-blue-400 rounded-full animate-bounce" style="animation-delay: 0.2s"></div>
										<div class="w-2 h-2 bg-blue-400 rounded-full animate-bounce" style="animation-delay: 0.4s"></div>
									</div>
								</div>
							</div>
						</div>
					</el-scrollbar>

					<!-- 输入和发送区域 -->
					<div class="flex items-center mt-2 space-x-2">
						<div class="relative flex-1">
							<input
								v-model="userInput"
								class="px-4 py-3 w-full text-gray-700 rounded-lg border border-gray-300 transition-all outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500"
								:placeholder="chatPlaceholder"
								@keyup.enter="sendMessage"
							/>
						</div>
						<el-button
							type="primary"
							class="flex items-center px-4 py-3 h-auto rounded-lg"
							@click="sendMessage"
							:disabled="!userInput.trim() || !canSendMessage"
						>
							<i class="mr-1 text-lg i-tabler-send"></i>
							发送
						</el-button>
					</div>
				</div>
			</div>

			<!-- 结果标签页 -->
			<div v-show="activeTab === 'result'">
				<div class="execution-detail">
					<div class="bg-green-50 rounded-lg border border-green-200">
						<div class="flex justify-between items-center">
							<div class="flex-1 py-2 text-center border-r border-green-200/80">
								<div class="mb-1 text-xs text-gray-600">状态</div>
								<div
									class="text-sm font-medium"
									:class="{
										'text-green-500': executionStatus.class === 'status-success',
										'text-red-500': executionStatus.class === 'status-error',
										'text-blue-500': executionStatus.class === 'status-running',
										'text-gray-400': executionStatus.class === 'status-pending',
									}"
								>
									{{ executionStatus.text }}
								</div>
							</div>
							<div class="flex-1 py-2 text-center border-r border-green-200/80">
								<div class="mb-1 text-xs text-gray-600">运行时间</div>
								<div class="text-sm font-medium text-green-500">{{ formattedExecutionTime }}</div>
							</div>
							<div class="flex-1 py-2 text-center">
								<div class="mb-1 text-xs text-gray-600">总 TOKEN 数</div>
								<div class="text-sm font-medium text-green-500">{{ totalTokens }} Tokens</div>
							</div>
						</div>
					</div>
				</div>
				<!-- 执行结果 -->
				<div class="p-4 mt-5" v-if="finalResult">
					<div class="panel-section">
						<div class="flex justify-between items-center mb-2 panel-header">
							<span class="text-sm font-medium">执行结果</span>
							<div class="flex gap-2">
								<el-button type="primary" size="small" @click="copyResult" class="flex items-center">
									<el-icon class="mr-1"><Document /></el-icon>
									复制
								</el-button>
							</div>
						</div>
						<code-editor v-model="resultJsonText" :json="true" :readonly="false" theme="nord" height="250px" />
					</div>
				</div>
			</div>

			<!-- 追踪标签页 -->
			<div v-show="activeTab === 'trace'" class="p-4">
				<!-- 执行进度状态指示器 -->
				<div v-if="isExecuting" class="flex flex-col justify-center items-center mb-6">
					<div class="flex justify-center items-center mb-3">
						<div class="loading loading-spinner loading-md text-primary"></div>
						<span class="ml-3 text-sm font-medium text-gray-700">正在执行中...</span>
					</div>
				</div>

				<!-- 执行完成状态 -->
				<div v-if="isExecutionComplete" class="flex justify-center items-center py-2 mb-6">
					<div class="flex justify-center items-center">
						<div
							class="flex justify-center items-center w-6 h-6 rounded-full"
							:class="{ 'bg-green-100': executionStatus.class === 'status-success', 'bg-red-100': executionStatus.class === 'status-error' }"
						>
							<i
								class="text-lg"
								:class="{
									'i-tabler-check text-green-500': executionStatus.class === 'status-success',
									'i-tabler-x text-red-500': executionStatus.class === 'status-error',
								}"
							></i>
						</div>
						<span
							class="ml-2 text-sm font-medium"
							:class="{ 'text-green-600': executionStatus.class === 'status-success', 'text-red-600': executionStatus.class === 'status-error' }"
						>
							{{ executionStatus.text }}
						</span>
					</div>
				</div>

				<!-- 执行进度 -->
				<node-list :nodes="executionNodes" @end="handleEnd" />
			</div>
		</div>
	</el-drawer>
</template>

<script setup>
import { ref, computed, watch, nextTick, onMounted, onUpdated } from 'vue';
import NodeList from './components/NodeList.vue';
import CodeEditor from './components/CodeEditor.vue';
import { Document } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
import MdRenderer from '/@/components/MdRenderer/MdRenderer.vue';
import { deleteConversation } from '/@/views/knowledge/aiChat/ts/gpt';

// 定义组件属性
const props = defineProps({
	modelValue: {
		type: Boolean,
		default: false,
	},
	id: {
		type: [String, Number],
		default: '',
	},
	executionNodes: {
		type: Array,
		default: () => [],
	},
	finalResult: {
		type: Object,
		default: null,
	},
	executionTime: {
		type: [Number, String],
		default: 0,
	},
	totalTokens: {
		type: Number,
		default: 0,
	},
	startParams: {
		type: Array,
		default: () => [],
	},
	conversationId: {
		type: String,
		default: '',
	},
});

// 定义需要发送的事件
const emit = defineEmits(['update:modelValue', 'close', 'run', 'update:stream']);

// 响应式状态
const form = ref({});
const activeTab = ref('');
const showError = ref(false);
const isExecuting = ref(false);
const chat = ref({
	showParams: true,
	contentId: '',
	isStream: true,
});
const chatMessages = ref([]);
const userInput = ref('');
const isLoading = ref(false);
const isAtBottom = ref(true);
const chatScrollbarRef = ref(null);
const chatContentRef = ref(null);
const streamingMessageIndex = ref(-1); // 正在流式传输的消息索引
const currentStreamContent = ref(''); // 当前流式内容
const resultJsonText = ref(''); // 可编辑的结果JSON文本
let scrollDebounceTimer = null; // 滚动防抖定时器

// 改进滚动到底部的逻辑
const scrollToBottom = (smooth = true) => {
	if (!chatScrollbarRef.value) return;

	nextTick(() => {
		try {
			const wrapper = chatScrollbarRef.value.wrapRef;
			if (!wrapper) return;

			// 使用 requestAnimationFrame 确保在下一帧渲染前执行滚动
			requestAnimationFrame(() => {
				const scrollHeight = wrapper.scrollHeight;

				// 对于流式传输，使用平滑滚动；对于快速更新，直接滚动
				if (smooth && !streamingMessageIndex.value !== -1) {
					wrapper.scrollTo({
						top: scrollHeight,
						behavior: 'smooth',
					});
				} else {
					// 立即滚动，用于流式传输场景
					chatScrollbarRef.value.setScrollTop(scrollHeight);
				}

				// 确保滚动生效的备用方案
				setTimeout(() => {
					if (wrapper.scrollTop + wrapper.clientHeight < scrollHeight - 10) {
						chatScrollbarRef.value.setScrollTop(scrollHeight);
					}
					isAtBottom.value = true;
				}, smooth ? 100 : 10);
			});
		} catch (error) {
			// 静默处理错误
		}
	});
};

// 专门用于流式传输的滚动函数（带防抖）
const scrollToBottomForStreaming = () => {
	if (!chatScrollbarRef.value || streamingMessageIndex.value === -1) return;
	
	// 清除之前的定时器
	if (scrollDebounceTimer) {
		clearTimeout(scrollDebounceTimer);
	}
	
	// 设置防抖，避免过度频繁的滚动
	scrollDebounceTimer = setTimeout(() => {
		nextTick(() => {
			try {
				const wrapper = chatScrollbarRef.value.wrapRef;
				if (!wrapper) return;
				
				// 检查是否需要滚动（只有在用户在底部时才自动滚动）
				if (isAtBottom.value) {
					const scrollHeight = wrapper.scrollHeight;
					chatScrollbarRef.value.setScrollTop(scrollHeight);
				}
			} catch (error) {
				// 静默处理错误
			}
		});
	}, 50); // 50ms 防抖延迟
};

const handleRun = () => {
	// 验证必填参数
	const hasError = props.startParams.some((param) => param.required && !param.value);
	showError.value = hasError;

	if (hasError) {
		ElMessage.warning('请填写所有必填参数');
		return;
	}

	isExecuting.value = true;

	emit('run', props.startParams);
	showError.value = false;
};

const handleEnd = () => {
	isExecuting.value = false;
};

const copyResult = () => {
	if (resultJsonText.value) {
		navigator.clipboard
			.writeText(resultJsonText.value)
			.then(() => {
				ElMessage.success('复制成功');
			})
			.catch(() => {
				ElMessage.error('复制失败');
			});
	}
};

const handleClear = async () => {
	if (props.conversationId) {
		try {
			await deleteConversation(props.conversationId);
		} catch (error) {
			ElMessage.error('清空会话失败');
		}
	}
	chatMessages.value = [];
	isLoading.value = false;
	isExecuting.value = false;
	streamingMessageIndex.value = -1;
	currentStreamContent.value = '';
	
	// 清理防抖定时器
	if (scrollDebounceTimer) {
		clearTimeout(scrollDebounceTimer);
		scrollDebounceTimer = null;
	}
	
	ElMessage.success('聊天记录已清空');
};

const handleScroll = (e) => {
	// Store scroll position info if needed for auto-scrolling behavior
	const { scrollTop, scrollHeight, clientHeight } = e;
	isAtBottom.value = scrollTop + clientHeight >= scrollHeight - 10;
};

// 添加鼠标滚轮事件处理
const handleWheel = (e) => {
	if (!chatScrollbarRef.value || !chatScrollbarRef.value.wrapRef) return;

	// 阻止默认滚动行为，使用自定义滚动
	e.preventDefault();

	// 平滑滚动处理
	smoothScroll(e);
};

// 平滑滚动处理函数
const smoothScroll = (e) => {
	// 获取滚动容器
	const wrapper = chatScrollbarRef.value.wrapRef;

	// 计算滚动距离，根据内容高度动态调整滚动速度
	const contentHeight = wrapper.scrollHeight;
	const viewportHeight = wrapper.clientHeight;
	const contentRatio = contentHeight / viewportHeight;

	// 滚动速度系数: 内容越多，滚动越快
	const speedFactor = Math.max(1, Math.min(3, contentRatio / 5));

	// 计算滚动距离，使用 deltaY 滚动方向
	const delta = e.deltaY * speedFactor;

	// 获取当前滚动位置并计算新位置
	const currentScrollTop = wrapper.scrollTop;
	const newScrollTop = Math.max(0, Math.min(currentScrollTop + delta, contentHeight - viewportHeight));

	// 平滑滚动到新位置
	chatScrollbarRef.value.setScrollTop(newScrollTop);

	// 更新是否位于底部的状态
	isAtBottom.value = newScrollTop + viewportHeight >= contentHeight - 10;
};

// 计算属性
const visible = computed({
	get: () => props.modelValue,
	set: (value) => emit('update:modelValue', value),
});

const executionStatus = computed(() => {
	// 优先从 finalResult 的 nodes 中获取状态信息
	if (props.finalResult?.result?.nodes && props.finalResult.result.nodes.length > 0) {
		const nodes = props.finalResult.result.nodes;
		const lastNode = nodes[nodes.length - 1];
		
		if (lastNode && lastNode.status) {
			const statusMap = {
				running: { text: '运行中', class: 'status-running' },
				success: { text: '成功', class: 'status-success' },
				error: { text: '失败', class: 'status-error' },
				skipped: { text: '已跳过', class: 'status-skipped' },
			};
			return statusMap[lastNode.status] || { text: '等待中', class: 'status-pending' };
		}
	}
	
	// 如果没有 finalResult 的 nodes，则使用 executionNodes
	const lastNode = props.executionNodes[props.executionNodes.length - 1];

	if (!lastNode) return { text: '等待中', class: 'status-pending' };

	const statusMap = {
		running: { text: '运行中', class: 'status-running' },
		success: { text: '成功', class: 'status-success' },
		error: { text: '失败', class: 'status-error' },
		skipped: { text: '已跳过', class: 'status-skipped' },
	};

	return statusMap[lastNode.status] || { text: '等待中', class: 'status-pending' };
});

const hasStartParams = computed(() => props.startParams && props.startParams.length > 0);

const isExecutionComplete = computed(() => {
	return props.executionNodes.length > 0 && (executionStatus.value.class === 'status-success' || executionStatus.value.class === 'status-error');
});

const formattedExecutionTime = computed(() => {
	if (!props.executionTime) return '0秒';

	// 将毫秒转换为秒
	const seconds = Number(props.executionTime) / 1000;

	// 保留3位小数并添加单位
	return `${seconds.toFixed(3)}秒`;
});

const startParamsForChat = computed(() => {
	return props.startParams.filter((e) => e.inputType == 'input' || e.inputType == 'string');
});

const chatPlaceholder = computed(() => {
	if (!chat.value.contentId) {
		return '请先在设置中选择对话字段';
	}
	return '输入您的问题...';
});

// 添加判断是否可以发送消息的计算属性
const canSendMessage = computed(() => {
	// 如果没有选择对话字段，不能发送
	if (!chat.value.contentId) return false;

	// 遍历startParams，找到匹配contentId的参数并赋值
	props.startParams.forEach((param) => {
		if (param.type === chat.value.contentId) {
			param.value = userInput.value;
		}
	});

	// 检查必填参数是否都已填写
	const hasEmptyRequired = props.startParams.some((param) => param.required && !param.value);
	return !hasEmptyRequired;
});

// 添加过滤参数的方法
const filteredParams = computed(() => {
	// 过滤掉内容字段，只展示其他字段
	if (!chat.value.contentId) return [];

	return props.startParams.filter((param) => {
		// 确保参数存在且类型不是当前选中的内容字段
		return param && param.type !== chat.value.contentId;
	});
});

// 将参数分组，每行两个
const groupedParams = computed(() => {
	const params = filteredParams.value;
	const groups = [];

	// 每两个参数为一组
	for (let i = 0; i < params.length; i += 2) {
		// 添加当前参数和下一个参数（如果存在）到一组
		const group = [params[i]];
		if (i + 1 < params.length) {
			group.push(params[i + 1]);
		}
		groups.push(group);
	}

	return groups;
});

// 将下方的sendMessage函数的检查逻辑修改为：
const sendMessage = () => {
	if (!userInput.value.trim()) return;

	// Check if content field is selected
	if (!chat.value.contentId) {
		// Show error message if no content field is selected
		chatMessages.value.push({
			role: 'ai',
			content: '请先在设置中选择对话字段。',
		});
		userInput.value = '';
		return;
	}

	// 验证必填参数
	const hasError = props.startParams.some((param) => param.required && !param.value);
	showError.value = hasError;

	if (hasError) {
		chatMessages.value.push({
			role: 'ai',
			content: '请先填写所有必填参数。',
		});
		return;
	}

	// Add user message to chat
	chatMessages.value.push({
		role: 'user',
		content: userInput.value,
	});

	// 遍历startParams，找到匹配contentId的参数并赋值
	props.startParams.forEach((param) => {
		if (param.type === chat.value.contentId) {
			param.value = userInput.value;
		}
	});

	// 根据stream参数决定是否添加流式传输占位符
	if (chat.value.isStream) {
		// 立即添加一个空的AI消息作为流式传输的占位符
		const aiMessageIndex = chatMessages.value.length;
		chatMessages.value.push({
			role: 'ai',
			content: '',
			isStreaming: true,
		});
		
		streamingMessageIndex.value = aiMessageIndex;
		currentStreamContent.value = '';
		// 由于已经有流式消息占位符，不需要额外的 loading 状态
		isLoading.value = false;
	} else {
		// 对于非流式调用，显示loading状态
		isLoading.value = true;
		streamingMessageIndex.value = -1;
	}
	
	userInput.value = '';

	// Force scroll to bottom after sending message
	scrollToBottom();

	// Run the flow with the user input
	handleRun();
};

// 观察器
watch(
	() => props.finalResult,
	(newResult) => {
		if (!newResult || typeof newResult !== 'object') return;

		// 处理流式聊天消息
		if (newResult.chatMessage !== undefined) {
			const currentMessage = chatMessages.value[streamingMessageIndex.value];
			if (currentMessage && currentMessage.role === 'ai') {
				// 更新流式消息内容
				currentMessage.content = newResult.chatMessage;
				
				// 检查是否完成流式传输
				if (!newResult.isStreaming) {
					currentMessage.isStreaming = false;
					streamingMessageIndex.value = -1;
					isLoading.value = false;
					isExecuting.value = false;
				}
				
				// 滚动到底部（流式传输时使用专门的滚动函数）
				if (newResult.isStreaming) {
					scrollToBottomForStreaming();
				} else {
					scrollToBottom(false);
				}
			}
			return;
		}

		// 处理传统的执行结果（非流式调用）
		isExecuting.value = false;

		// 如果没有流式消息，但有结果，显示传统格式
		if (newResult.result) {
			let responseText = '';
			
			// 如果有聊天消息字段，优先显示
			if (newResult.chatMessage) {
				responseText = newResult.chatMessage;
			} else {
				responseText = JSON.stringify(newResult.result, null, 2);
			}

			// 对于非流式调用，直接添加AI消息
			if (!chat.value.isStream) {
				chatMessages.value.push({
					role: 'ai',
					content: responseText,
					isStreaming: false,
				});
			} else {
				// 更新当前的AI消息
				const currentMessage = chatMessages.value[streamingMessageIndex.value];
				if (currentMessage && currentMessage.role === 'ai') {
					currentMessage.content = responseText;
					currentMessage.isStreaming = false;
				} else {
					chatMessages.value.push({
						role: 'ai',
						content: responseText,
						isStreaming: false,
					});
				}
			}

			isLoading.value = false;
			streamingMessageIndex.value = -1;
			scrollToBottom();
		}
	},
	{ deep: true }
);

// Also watch for execution status changes
watch(
	() => executionStatus.value,
	(newStatus) => {
		if (newStatus.text === '失败') {
			// 如果有正在流式传输的消息，更新它的内容
			if (streamingMessageIndex.value !== -1) {
				const currentMessage = chatMessages.value[streamingMessageIndex.value];
				if (currentMessage && currentMessage.role === 'ai') {
					currentMessage.content = '执行失败，请查看追踪标签页了解详情。';
					currentMessage.isStreaming = false;
				}
				streamingMessageIndex.value = -1;
			} else if (isLoading.value) {
				// 如果只是 loading 状态，添加新的失败消息
				chatMessages.value.push({
					role: 'ai',
					content: '执行失败，请查看追踪标签页了解详情。',
				});
			}
			isLoading.value = false;
		}
	}
);

watch(
	chatMessages,
	() => {
		// Always scroll to bottom when messages change
		// Add a small delay to ensure content has been rendered
		setTimeout(() => {
			scrollToBottom();
		}, 50);
	},
	{ deep: true, immediate: true }
);

watch(isExecutionComplete, (newVal) => {
	if (newVal) {
		isExecuting.value = false;
	}
});

// 同步resultJsonText与finalResult
watch(
	() => props.finalResult,
	(newResult) => {
		if (newResult) {
			resultJsonText.value = JSON.stringify(newResult, null, 2);
		} else {
			resultJsonText.value = '';
		}
	},
	{ immediate: true }
);

// 监听stream变化并通知父组件
watch(
	() => chat.value.isStream,
	(newValue) => {
		emit('update:stream', newValue);
	},
	{ immediate: true }
);

// 生命周期钩子
onMounted(() => {
	activeTab.value = hasStartParams.value ? 'run' : 'trace';
});

onUpdated(() => {
	// Ensure scroll is at bottom when component is updated
	if (isAtBottom.value) {
		scrollToBottom();
	}
});
</script>

<style lang="scss">
.execution-drawer {
	.el-drawer__body {
		padding: 0;
	}

	// 自定义滚动条样式
	.el-scrollbar__bar {
		opacity: 0.3;
		transition: opacity 0.3s;

		&.is-horizontal {
			height: 6px;
		}

		&.is-vertical {
			width: 6px;
		}

		&:hover {
			opacity: 0.8;
		}
	}

	.el-scrollbar__thumb {
		background-color: rgba(144, 147, 153, 0.5);
		border-radius: 4px;

		&:hover {
			background-color: rgba(144, 147, 153, 0.8);
		}
	}
}

.tab-container {
	display: flex;
	border-bottom: 1px solid #e4e7ed;
	background: white;
	padding: 0 16px;
	position: sticky;
	top: 0;
	z-index: 10;
}

.tab-item {
	position: relative;
	padding: 12px 20px;
	cursor: pointer;
	color: #909399;
	font-size: 14px;
	transition: all 0.3s;
	user-select: none;
	margin-right: 32px;

	&:hover {
		color: #409eff;
	}

	&.active {
		color: #409eff;
		font-weight: 500;

		&:after {
			content: '';
			position: absolute;
			bottom: -1px;
			left: 0;
			right: 0;
			height: 2px;
			background: #409eff;
			border-radius: 1px;
		}
	}
}

.panel-section {
	background-color: #fff;
	border-radius: 4px;
	box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
	overflow: hidden;
}

.panel-header {
	padding: 8px 12px;
	font-weight: 500;
	color: #303133;
	background-color: #f5f7fa;
	border-bottom: 1px solid #e4e7ed;
}

/* Chat styles */
.chat-container {
	display: flex;
	flex-direction: column;
	height: 100%;
}

.chat-messages {
	flex: 1;
	overflow-y: auto;
	padding: 16px;
	scroll-behavior: smooth;
}

.el-scrollbar__wrap {
	scroll-behavior: smooth;
}

.message {
	margin-bottom: 16px;

	&.user-message {
		display: flex;
		flex-direction: row-reverse;

		.message-content {
			background-color: #409eff;
			color: white;
			border-radius: 12px 12px 2px 12px;
			margin-right: 12px;
		}
	}

	&.ai-message {
		.message-content {
			background-color: #f5f7fa;
			color: #303133;
			border-radius: 12px 12px 12px 2px;
			margin-left: 12px;
		}
	}
}

.message-content {
	padding: 12px 16px;
	max-width: 80%;
	border-radius: 8px;
	box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
	word-break: break-word;
}

.message-input {
	display: flex;
	align-items: center;
	padding: 12px 16px;
	border-top: 1px solid #e4e7ed;
	background-color: white;

	input {
		flex: 1;
		padding: 10px 16px;
		border: 1px solid #dcdfe6;
		border-radius: 4px;
		outline: none;

		&:focus {
			border-color: #409eff;
		}
	}

	button {
		margin-left: 12px;
		display: flex;
		align-items: center;
		justify-content: center;
	}
}

/* Typing indicator animation */
.typing-indicator {
	display: flex;
	align-items: center;

	.dot {
		width: 8px;
		height: 8px;
		margin: 0 1px;
		background-color: #a0a0a0;
		border-radius: 50%;
		animation: bounce 1.4s infinite ease-in-out;

		&:nth-child(1) {
			animation-delay: -0.32s;
		}

		&:nth-child(2) {
			animation-delay: -0.16s;
		}
	}
}



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

/* Chat UI Animations */
.animate-fadeIn {
	animation: fadeIn 0.3s ease-in-out;
}

.animate-slideInRight {
	animation: slideInRight 0.3s ease-out;
}

.animate-slideInLeft {
	animation: slideInLeft 0.3s ease-out;
}

@keyframes fadeIn {
	from {
		opacity: 0;
	}
	to {
		opacity: 1;
	}
}

@keyframes slideInRight {
	from {
		transform: translateX(20px);
		opacity: 0;
	}
	to {
		transform: translateX(0);
		opacity: 1;
	}
}

@keyframes slideInLeft {
	from {
		transform: translateX(-20px);
		opacity: 0;
	}
	to {
		transform: translateX(0);
		opacity: 1;
	}
}

/* Style for chat content */
.prose {
	img {
		max-width: 100%;
		border-radius: 4px;
	}

	pre {
		background-color: #f8f9fa;
		border-radius: 4px;
		padding: 12px;
		overflow-x: auto;
		margin: 16px 0;
	}

	code {
		font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
		font-size: 0.9em;
		padding: 2px 4px;
		background: #f1f5f9;
		border-radius: 3px;
	}

	p {
		margin-bottom: 0.75em;
	}

	h1,
	h2,
	h3,
	h4 {
		margin-top: 1em;
		margin-bottom: 0.5em;
		font-weight: 600;
	}

	ul,
	ol {
		padding-left: 1.5em;
		margin: 0.5em 0;
	}
}
</style>
