<template>

	<view class="content">
		<!-- 合并后的顶部区域 -->
		<view class="header-combined">
			<view class="left-section">
				<view class="back-btn" @tap="goBack">
					<text class="back-icon">←</text>
					<text class="back-text">返回</text>
				</view>
			</view>
			<view class="middle-section">
				<view class="logo-container">
					<text class="logo-icon">✈️</text>
					<text class="main-title">Gooh旅行</text>
				</view>
				<text class="sub-title">智能旅行规划专家</text>
			</view>
			<view class="right-section">
				<!-- <view class="test-btn" @tap="testConnection" v-if="isDevelopment">
					<text class="test-text">测试</text>
				</view>
				<view class="console-btn" @tap="testConsoleLog" v-if="isDevelopment">
					<text class="console-text">测试控制台</text>
				</view> -->
				<view class="new-chat-btn" @tap="createNewChat">
					<text class="new-chat-icon">+</text>
					<text class="new-chat-text">新建对话</text>
				</view>
			</view>
		</view>
		
		<!-- 聊天头部信息 -->
		<view class="chat-header">
			<view class="assistant-name">
				<view class="dot"></view>
				<text>旅行AI助手</text>
			</view>
		</view>
		
		<!-- 消息内容区域 -->
		<view class="message-container">
			<!-- 消息列表 -->
			<scroll-view 
				class="message-list" 
				scroll-y="true" 
				:scroll-top="scrollTop"
				:scroll-with-animation="true"
				@scrolltoupper="loadMoreMessages"
			>
				<!-- 欢迎消息与快捷问题组合 -->
				<view class="welcome-container" v-if="messages.length > 0 && messages[0].type === 'ai'">
					<view class="welcome-message">
						<view class="avatar">
							<image src="/static/images/ai-avatar.png" mode="aspectFill"></image>
						</view>
						<view class="message-bubble">
							<rich-text :nodes="messages[0].content"></rich-text>
						</view>
					</view>
					
					<!-- 快捷问题区域 -->
					<view class="quick-questions">
						<view 
							v-for="(question, key) in quickQuestions" 
							:key="key"
							class="quick-question"
							@tap="handleQuickQuestion(key)"
						>
							<view class="dot-marker"></view>
							<text class="question-text">{{ key }}</text>
							<view class="arrow-icon">
								<text>›</text>
							</view>
						</view>
					</view>
				</view>
				
				<!-- 其他消息 -->
				<view 
					v-for="(msg, index) in displayMessages" 
					:key="index" 
					:class="['message-item', msg.type]"
				>
					<!-- 消息头部（时间和角色） -->
					<view class="message-header">
						<text class="message-time">{{ formatTime(msg.timestamp) }}</text>
						<text class="message-role">{{ msg.type === 'user' ? '我' : 'AI助手' }}</text>
					</view>
					
					<!-- 消息内容 -->
					<view class="message-content">
						<view class="avatar">
							<image :src="msg.type === 'user' ? '/static/images/user-avatar.png' : '/static/images/ai-avatar.png'" mode="aspectFill"></image>
						</view>
						<view class="message-bubble">
							<rich-text v-if="!msg.isThinking && msg.type !== 'ai-plan'" :nodes="msg.content"></rich-text>
							<view v-else-if="msg.type === 'ai-plan'" class="travel-plan-card">
								<!-- 计划头部 -->
								<view class="travel-plan-header">
									<view class="plan-logo">
										<text>Gooh</text>
									</view>
								</view>
								
								<!-- 基本信息 -->
								<view class="travel-plan-basic">
									<view class="travel-plan-title">
										<text>{{msg.planData.name}}</text>
									</view>
									<view class="travel-plan-desc">
										<text>{{msg.planData.description}}</text>
									</view>
									<view class="travel-plan-feature">
										<text>{{msg.planData.features}}</text>
									</view>
									<view class="travel-plan-price">
										<text>¥{{msg.planData.price}}</text><text v-if="msg.planData.price.includes('-')">(单人经济型)</text>
									</view>
								</view>
								
								<!-- 行程安排 -->
								<view class="travel-plan-schedule">
									<!-- 日历指示器 -->
									<view class="calendar-indicator">
										<text class="month">July</text>
										<text class="day">17</text>
									</view>
									<view class="schedule-title">行程安排</view>
								</view>
								
								<!-- 天数指示器 -->
								<view class="day-indicator">
									<view class="pin-icon">📍</view>
									<text class="day-text">第{{msg.planData.currentDay}}天</text>
								</view>
								
								<!-- 行程详情 -->
								<view class="travel-details">
									<view class="detail-item">
										<text class="detail-label">旅游地点:</text>
										<text class="detail-value">{{msg.planData.city}}</text>
									</view>
									<view class="detail-item" v-if="msg.planData.attractions">
										<text class="detail-label">地点:</text>
										<text class="detail-value">{{msg.planData.attractions}}</text>
									</view>
									<view class="detail-item" v-if="msg.planData.food">
										<text class="detail-label">周边美食:</text>
										<text class="detail-value">{{msg.planData.food}}</text>
									</view>
									<view class="detail-item">
										<text class="detail-label">安排说明:</text>
										<text class="detail-value">{{msg.planData.arrangement}}</text>
									</view>
								</view>
								
								<!-- 底部信息 -->
								<view class="travel-footer">
									<view class="footer-item">
										<text>{{msg.planData.days}}</text>
									</view>
									<view class="footer-item">
										<text>总花费约为: ¥{{msg.planData.price}}</text>
									</view>
									<view class="footer-item">
										<text>{{msg.planData.spots}}</text>
									</view>
								</view>
								
								<!-- 备注信息 -->
								<view class="travel-note" v-if="msg.planData.note">
									<text class="note-label">备注:</text>
									<text class="note-content">{{msg.planData.note}}</text>
								</view>
							</view>
							<view v-else class="thinking-dots">
								<text>.</text>
								<text>.</text>
								<text>.</text>
							</view>
						</view>
					</view>
				</view>
				
				<!-- 底部留白，防止被输入框遮挡 -->
				<view class="bottom-space"></view>
			</scroll-view>
		</view>

		<!-- 输入区域 -->
		<view class="input-area">
			<input 
				class="message-input"
				type="text"
				v-model="inputMessage"
				:disabled="isLoading"
				:maxlength="maxLength"
				
				placeholder="请输入您的问题（最多300字）"
				@confirm="sendMessage"
			/>
			<button 
				class="send-btn" 
				:disabled="isLoading || !inputMessage.trim()"
				:class="{ 'loading': isLoading }"
				@tap="sendMessage"
			>
				{{ isLoading ? '发送中...' : '发送' }}
			</button>
		</view>
	</view>
</template>

<script>
	// 导入AI API
	import { chatWithAI, startAISession, getWebSocketUrl, getSSEUrl, getLastAIReply, fetchServerResponse } from '@/pages/api/ai.js';
	import { baseUrl } from '@/pages/api/config.js';
	
	export default {
		data() {
			return {
				inputMessage: '',
				messages: [],
				isLoading: false,
				scrollTop: 0,
				maxLength: 300,
				userId: 'user_123', // 模拟用户ID
				sessionId: '',
				eventSource: null, // SSE连接对象
				pollingInterval: null, // 轮询定时器
				isConnected: false, // SSE连接状态
				isDevelopment: true, // 控制测试按钮显示
				
				// 快捷问题
				quickQuestions: {
					'重庆深度5日游': {
						destination: '重庆',
						days: 5,
						budget: 3000,
						preferences: ['景点', '美食', '文化'],
						transportation: '公共交通'
					},
					'推荐几个热门旅游城市': {
						requestType: 'recommendation',
						preferences: ['热门', '旅游城市']
					},
					'旅游注意事项有哪些': {
						requestType: 'travelTips',
						preferences: ['安全', '注意事项']
					}
				}
			}
		},
		computed: {
			// 用于显示除欢迎消息外的其他消息
			displayMessages() {
				// 如果没有消息或只有一条AI欢迎消息，返回空数组
				if (this.messages.length === 0 || (this.messages.length === 1 && this.messages[0].type === 'ai')) {
					return [];
				}
				
				// 如果有多条消息，返回除第一条欢迎消息外的所有消息
				if (this.messages.length > 1 && this.messages[0].type === 'ai') {
					return this.messages.slice(1);
				}
				
				// 否则返回所有消息
				return this.messages;
			}
		},
		onLoad(options) {
			// 检测环境并设置isDevelopment
			// #ifdef H5
			if (window && window.location) {
				this.isDevelopment = window.location.hostname === 'localhost' || window.location.hostname.includes('192.168');
			}
			// #endif
			
			// #ifdef MP-WEIXIN
			if (typeof __wxConfig !== 'undefined') {
				this.isDevelopment = __wxConfig.envVersion === 'develop' || __wxConfig.envVersion === 'trial';
			}
			// #endif
			
			// 从本地存储加载消息历史
			try {
				const savedMessages = uni.getStorageSync('chat_messages');
				if (savedMessages) {
					this.messages = JSON.parse(savedMessages);
				} else {
					// 如果没有历史消息，添加默认欢迎消息
					this.addMessage('您好，欢迎遇见Gooh旅记旅行规划师！我将为您设计专属行程，解答旅途中的各类问题，让旅行无忧。有任何想法，请随时告诉我~', 'ai');
				}
			} catch (e) {
				console.error('加载消息历史失败:', e);
				// 出错也添加欢迎消息
				this.addMessage('您好，欢迎遇见Gooh旅记旅行规划师！我将为您设计专属行程，解答旅途中的各类问题，让旅行无忧。有任何想法，请随时告诉我~', 'ai');
			}
			
			// 初始化会话
			this.startSession();
		},
		onUnload() {
			// 保存消息到本地存储
			try {
				uni.setStorageSync('chat_messages', JSON.stringify(this.messages));
			} catch (e) {
				console.error('保存消息历史失败:', e);
			}
			
			// 关闭SSE连接
			if (this.eventSource) {
				this.eventSource.close();
			}
			
			// 清除轮询
			this.stopPolling();
		},
		methods: {
			// 返回旅游规划页面
			goBack() {
				// 直接跳转到旅游规划页面
				uni.switchTab({
					url: '/pages/planning/index'
				});
			},
			
			// 创建新对话
			async createNewChat() {
				// 关闭现有SSE连接
				if (this.eventSource) {
					try {
						this.eventSource.close();
						this.eventSource = null;
					} catch (e) {
						console.error('关闭SSE连接失败:', e);
					}
				}
				
				// 清除轮询定时器
				if (this.pollingInterval) {
					clearInterval(this.pollingInterval);
					this.pollingInterval = null;
				}
				
				// 清空消息和输入
				this.messages = [];
				this.inputMessage = '';
				this.sessionId = '';
				
				// 开始新会话
				await this.startSession();
				
				uni.showToast({
					title: '已创建新对话',
					icon: 'none'
				});
			},
			
			// 开始新会话
			async startSession() {
				try {
					const response = await startAISession();
					
					if (response && response.code === 200 && response.sessionId) {
						this.sessionId = response.sessionId;
						console.log('会话创建成功，sessionId:', this.sessionId);
						
						// 只有在没有消息时才显示AI欢迎消息
						if (response.msg && this.messages.length === 0) {
							// 使用AI返回的欢迎消息
							this.addMessage(response.msg, 'ai');
						}
						
						// 确保WebSocket连接在sessionId存在时才建立
						if (this.sessionId) {
							await this.setupWebSocket();
						} else {
							throw new Error('未获取到有效的sessionId');
						}
					} else {
						throw new Error(response?.msg || '创建会话失败');
					}
				} catch (error) {
					console.error('创建会话失败:', error);
					uni.showToast({
						title: error.message || '连接失败，请重试',
						icon: 'none'
					});
				}
			},
			
			// 设置SSE连接
			async setupWebSocket() {
				if (!this.sessionId) {
					console.error('无法建立SSE连接：sessionId不存在');
					return;
				}
				
				// 获取SSE连接URL
				const url = getSSEUrl(this.sessionId);
				console.log('尝试连接SSE:', url);
				
				// 关闭已有的事件源
				if (this.eventSource) {
					try {
						this.eventSource.close();
						console.log('已关闭旧的SSE连接');
					} catch (e) {
						console.error('关闭旧SSE连接失败:', e);
					}
					this.eventSource = null;
				}
				
				return new Promise((resolve, reject) => {
					try {
						console.log('开始创建SSE连接...');
						
						// 使用EventSource创建SSE连接
						// #ifdef H5
						// 在H5环境下使用原生EventSource
						if (typeof window !== 'undefined' && window) {
							const EventSource = window.EventSource;
							if (!EventSource) {
								console.log('当前环境不支持EventSource，使用替代方法');
								// 在H5环境但不支持EventSource时，使用轮询
								this.isConnected = true;
								this.setupPolling();
								resolve();
								return;
							}
							
							this.eventSource = new EventSource(url);
							
							this.eventSource.onopen = (event) => {
								console.log('SSE连接已打开:', event);
								this.isConnected = true;
								resolve(event);
							};
							
							this.eventSource.onmessage = (event) => {
								console.log('收到SSE消息:', event);
								this.handleSocketMessage(event);
							};
							
							this.eventSource.onerror = (error) => {
								console.error('SSE连接错误:', error);
								this.isConnected = false;
								this.eventSource.close();
								this.eventSource = null;
								reject(new Error('SSE连接错误'));
							};
						} else {
							// 如果window不存在，使用替代方法
							console.log('window对象不存在，使用替代方法连接');
							this.isConnected = true;
							this.setupPolling();
							resolve();
						}
						// #endif
						
						// #ifdef MP-WEIXIN || APP-PLUS
						// 在小程序和APP环境下使用uni.request模拟SSE
						console.log('在小程序环境下使用替代方法连接SSE');
						this.isConnected = true;
						
						// 仅在加载状态时进行轮询，而不是一直轮询
						this.setupPolling();
						resolve();
						// #endif
						
						// 设置连接超时
						setTimeout(() => {
							if (!this.isConnected) {
								console.error('SSE连接超时');
								// #ifdef H5
								if (this.eventSource) {
									this.eventSource.close();
									this.eventSource = null;
								}
								// #endif
								reject(new Error('SSE连接超时'));
							}
						}, 10000); // 10秒超时
						
					} catch (error) {
						console.error('创建SSE连接时发生错误:', error);
						reject(error);
					}
				});
			},
			
			// 处理WebSocket消息
			handleSocketMessage(res) {
				try {
					console.log('开始处理WebSocket消息:', res.data);
					
					// 尝试解析消息数据
					let data;
					try {
						data = JSON.parse(res.data);
					} catch (parseError) {
						// 如果解析失败，可能是纯文本消息
						console.log('WebSocket数据不是JSON格式，尝试作为纯文本处理');
						data = {
							type: 'message',
							content: res.data
						};
					}
					
					console.log('处理后的WebSocket消息数据:', data);
					
					// 如果缺少type字段，默认为message类型
					if (!data.type && data.content) {
						data.type = 'message';
					}
							
					switch(data.type) {
						case 'start':
							console.log('收到start类型消息');
							// 只有在用户发送过消息后才显示"思考中"
							if (this.messages.length > 0 && this.messages[this.messages.length - 1].type === 'user') {
								this.addMessage('AI正在思考...', 'ai', true);
							}
							// 在小程序环境中，收到开始消息后启动轮询
							// #ifdef MP-WEIXIN || APP-PLUS
							this.setupPolling();
							// #endif
							break;
						case 'message':
							console.log('收到message类型消息:', data.content);
							if (this.messages.length > 0 && this.messages[this.messages.length - 1].isThinking) {
								this.messages.pop();
							}
							if (data.content) {
								// 检查是否是旅游行程信息
								const isPlanContent = this.checkIfTravelPlanContent(data.content);
								if (isPlanContent) {
									console.log('检测到旅游行程信息，解析为卡片显示');
									const planData = this.parseTravelPlanContent(data.content);
									this.addTravelPlanMessage(planData);
								} else {
									let formattedContent = this.formatAIResponse(data.content);
									this.addMessage(formattedContent, 'ai');
								}
							}
							break;
						case 'done':
							console.log('收到done类型消息');
							if (this.messages.length > 0 && this.messages[this.messages.length - 1].isThinking) {
								this.messages.pop();
							}
							this.isLoading = false;
							// 在小程序环境中，收到done消息后停止轮询
							// #ifdef MP-WEIXIN || APP-PLUS
							this.stopPolling();
							// #endif
							break;
						case 'error':
							console.error('收到error类型消息:', data.content);
							if (this.messages.length > 0 && this.messages[this.messages.length - 1].isThinking) {
								this.messages.pop();
							}
							this.addMessage(`错误: ${data.content}`, 'ai');
							this.isLoading = false;
							uni.showToast({
								title: '发生错误，请重试',
								icon: 'none'
							});
							// 在小程序环境中，收到错误消息后停止轮询
							// #ifdef MP-WEIXIN || APP-PLUS
							this.stopPolling();
							// #endif
							break;
						default:
							console.log('收到未知类型消息:', data);
							// 如果没有指定类型，但有内容，尝试显示内容
							if (data.content || (typeof data === 'string' && data)) {
								const content = data.content || data;
								if (this.messages.length > 0 && this.messages[this.messages.length - 1].isThinking) {
									this.messages.pop();
								}
								let formattedContent = this.formatAIResponse(content);
								this.addMessage(formattedContent, 'ai');
							}
							break;
					}
				} catch (error) {
					console.error('处理WebSocket消息失败:', error);
					this.isLoading = false;
					
					// 尝试直接显示消息内容，无论格式如何
					try {
						let content = res.data;
						// 如果消息是字符串，直接显示
						if (typeof content === 'string' && content.length > 0) {
							console.log('尝试直接显示原始消息内容');
							if (this.messages.length > 0 && this.messages[this.messages.length - 1].isThinking) {
								this.messages.pop();
							}
							let formattedContent = this.formatAIResponse(content);
							this.addMessage(formattedContent, 'ai');
							return;
						}
					} catch (e) {
						console.error('尝试直接显示消息内容也失败:', e);
					}
					
					if (this.messages.length > 0 && this.messages[this.messages.length - 1].isThinking) {
						this.messages.pop();
					}
					this.addMessage('消息处理出错，请重试', 'ai');
				}
			},
			
			// 设置轮询 - 仅当需要时才开始轮询，有结果就停止
			setupPolling() {
				console.log('设置轮询检查');
				// 先清除之前的轮询
				this.stopPolling();
				
				// 记录轮询次数
				this.pollingCount = 0;
				const maxPollingCount = 20; // 最多轮询20次，约60秒
				
				// 开始新的轮询
				this.pollingInterval = setInterval(async () => {
					try {
						this.pollingCount++;
						console.log(`第${this.pollingCount}次轮询检查`);
						
						// 如果不在加载状态或轮询次数太多，停止轮询
						if (!this.isLoading || this.pollingCount > maxPollingCount) {
							console.log('条件不满足，停止轮询：', { 
								isLoading: this.isLoading, 
								pollingCount: this.pollingCount 
							});
							this.stopPolling();
							return;
						}
						
						// 检查是否有新消息
						const response = await getLastAIReply(this.sessionId);
						console.log('轮询结果:', response);
						
						// 如果有回复内容，模拟收到消息事件
						if (response && response.code === 200 && response.reply) {
							console.log('轮询发现新消息');
							this.handleSocketMessage({
								data: JSON.stringify({
									type: 'message',
									content: response.reply
								})
							});
							
							// 收到回复后，模拟一个done消息
							setTimeout(() => {
								this.handleSocketMessage({
									data: JSON.stringify({
										type: 'done'
									})
								});
							}, 500);
							
							// 停止轮询
							this.stopPolling();
						}
					} catch (err) {
						console.error('轮询出错:', err);
						this.pollingErrorCount = (this.pollingErrorCount || 0) + 1;
						
						// 如果连续错误太多，停止轮询
						if (this.pollingErrorCount > 3) {
							console.log('轮询错误太多，停止轮询');
							this.stopPolling();
						}
					}
				}, 3000); // 每3秒轮询一次
			},
			
			// 停止轮询
			stopPolling() {
				if (this.pollingInterval) {
					console.log('停止轮询');
					clearInterval(this.pollingInterval);
					this.pollingInterval = null;
					this.pollingCount = 0;
					this.pollingErrorCount = 0;
				}
			},
			
			// 发送消息
			async sendMessage() {
				if (!this.inputMessage.trim() || this.isLoading) return;
				
				console.log('准备发送消息:', this.inputMessage);
				
				// 确保有sessionId
				if (!this.sessionId) {
					console.log('sessionId不存在，先创建新会话');
					try {
						const response = await startAISession();
						if (response && response.code === 200 && response.sessionId) {
							this.sessionId = response.sessionId;
							console.log('新会话创建成功，sessionId:', this.sessionId);
						} else {
							throw new Error('创建会话失败');
						}
					} catch (error) {
						console.error('创建会话失败:', error);
						uni.showToast({
							title: '创建会话失败，请重试',
							icon: 'none'
						});
						return;
					}
				}
				
				if (this.inputMessage.length > this.maxLength) {
					uni.showToast({
						title: `消息不能超过${this.maxLength}字`,
						icon: 'none'
					});
					return;
				}
				
				// 保存当前消息并清空输入框
				const messageToSend = this.inputMessage.trim();
				this.inputMessage = '';
				
				// 添加用户消息
				this.addMessage(messageToSend, 'user');
				
				// 设置加载状态
				this.isLoading = true;
				
				try {
					// 检查SSE连接状态
					if (!this.isConnected) {
						console.warn('SSE未连接，尝试重新连接');
						await this.setupWebSocket();
						console.log('SSE重连状态:', this.isConnected ? '已连接' : '未连接');
					}

					// 发送HTTP请求
					console.log('发送消息到服务器:', {
						sessionId: this.sessionId,
						message: messageToSend
					});

					// 发送消息并等待响应
					const response = await chatWithAI(this.sessionId, messageToSend);
					console.log('服务器响应:', response);
					
					if (response.code === 200) {
						// 直接显示服务器返回的消息作为AI助手回复
						if (response.msg) {
							console.log('服务器返回的消息:', response.msg);
							let formattedContent = this.formatAIResponse(response.msg);
							this.addMessage(formattedContent, 'ai');
						} else {
							// 如果没有msg字段，等待WebSocket响应
							console.log('服务器未返回消息，等待WebSocket响应');
						}
						
						// 小程序环境中启动轮询
						// #ifdef MP-WEIXIN || APP-PLUS
						console.log('小程序环境中启动轮询检查');
						this.setupPolling();
						// #endif
					} else if (response.code === 404) {
						console.warn('会话不存在，尝试重新开始会话');
						const newSessionResponse = await startAISession();
						if (newSessionResponse && newSessionResponse.code === 200 && newSessionResponse.sessionId) {
							this.sessionId = newSessionResponse.sessionId;
							// 重新发送消息
							const retryResponse = await chatWithAI(this.sessionId, messageToSend);
							console.log('重试响应:', retryResponse);
							
							if (retryResponse.code === 200) {
								// 显示重试后服务器返回的消息
								if (retryResponse.msg) {
									console.log('重试后服务器返回的消息:', retryResponse.msg);
									let formattedContent = this.formatAIResponse(retryResponse.msg);
									this.addMessage(formattedContent, 'ai');
								}
							} else {
								throw new Error(retryResponse.msg || '重试发送失败');
							}
						} else {
							throw new Error('重新创建会话失败');
						}
					} else {
						throw new Error(response.msg || '发送失败');
					}
				} catch (error) {
					console.error('发送消息失败:', error);
					uni.showToast({
						title: error.message || '发送失败，请重试',
						icon: 'none'
					});
					this.addMessage('抱歉，发送消息失败，请重试。', 'ai');
				} finally {
					this.isLoading = false;
				}
			},
			
			// 处理快捷问题
			async handleQuickQuestion(question) {
				if (this.isLoading) return;
				
				console.log('处理快捷问题:', question);
				this.isLoading = true;
				
				try {
					// 确保有sessionId
					if (!this.sessionId) {
						console.log('sessionId不存在，先创建新会话');
						try {
							const response = await startAISession();
							if (response && response.code === 200 && response.sessionId) {
								this.sessionId = response.sessionId;
								console.log('新会话创建成功，sessionId:', this.sessionId);
							} else {
								throw new Error('创建会话失败');
							}
						} catch (error) {
							console.error('创建会话失败:', error);
							uni.showToast({
								title: '创建会话失败，请重试',
								icon: 'none'
							});
							this.isLoading = false;
							return;
						}
					}
					
					// 添加用户消息
					this.addMessage(question, 'user');
					
					// 发送HTTP请求
					console.log('发送快捷问题到服务器:', {
						sessionId: this.sessionId,
						message: question
					});
					
					const response = await chatWithAI(this.sessionId, question);
					console.log('快捷问题服务器响应:', response);
					
					if (response.code === 200) {
						// 直接显示服务器返回的消息作为AI助手回复
						if (response.msg) {
							console.log('服务器返回的消息:', response.msg);
							let formattedContent = this.formatAIResponse(response.msg);
							this.addMessage(formattedContent, 'ai');
						} else {
							// 如果没有msg字段，等待WebSocket响应
							console.log('服务器未返回消息，等待WebSocket响应');
						}
						
						// 小程序环境中启动轮询
						// #ifdef MP-WEIXIN || APP-PLUS
						console.log('小程序环境中启动轮询检查');
						this.setupPolling();
						// #endif
					} else if (response.code === 404) {
						console.warn('会话不存在，尝试重新开始会话');
						this.addMessage('会话已过期，正在重新创建会话...', 'system');
						
						const newSessionResponse = await startAISession();
						if (newSessionResponse && newSessionResponse.code === 200 && newSessionResponse.sessionId) {
							this.sessionId = newSessionResponse.sessionId;
							// 重新发送消息
							this.handleQuickQuestion(question);
						} else {
							throw new Error('重新创建会话失败');
						}
					} else {
						throw new Error(response.msg || '发送失败');
					}
				} catch (error) {
					console.error('处理快捷问题失败:', error);
					uni.showToast({
						title: error.message || '发送失败，请重试',
						icon: 'none'
					});
					this.addMessage('抱歉，处理问题失败，请重试。', 'ai');
				} finally {
					this.isLoading = false;
				}
			},
			
			// 添加消息
			addMessage(content, type, isThinking = false) {
				console.log('添加新消息:', { content, type, isThinking });
				
				// 如果是用户消息，转义HTML特殊字符
				if (type === 'user') {
					content = content.replace(/</g, '&lt;').replace(/>/g, '&gt;');
				}
				
				const message = {
					type: type,
					content: content,
					isThinking: isThinking,
					timestamp: Date.now()
				};
				
				// 如果是思考状态的消息，检查是否需要替换之前的思考状态
				if (!isThinking && this.messages.length > 0) {
					const lastMessage = this.messages[this.messages.length - 1];
					if (lastMessage.isThinking && lastMessage.type === type) {
						console.log('替换思考状态消息');
						this.messages.splice(-1, 1);
					}
				}
				
				this.messages.push(message);
				console.log('当前消息列表:', this.messages);
				
				// 保存到本地存储
				try {
					uni.setStorageSync('chat_messages', JSON.stringify(this.messages));
					console.log('消息已保存到本地存储');
				} catch (e) {
					console.error('保存消息到本地存储失败:', e);
				}
				
				this.$nextTick(() => {
					this.scrollToBottom();
				});
			},
			
			// 滚动到底部
			scrollToBottom() {
				// 获取消息列表的高度
				const query = uni.createSelectorQuery().in(this);
				query.select('.message-list').boundingClientRect(data => {
					if (data) {
						this.scrollTop = data.height;
					}
				}).exec();
			},
			
			// 格式化时间
			formatTime(timestamp) {
				if (!timestamp) return '';
				const date = new Date(timestamp);
				const hours = date.getHours().toString().padStart(2, '0');
				const minutes = date.getMinutes().toString().padStart(2, '0');
				return `${hours}:${minutes}`;
			},

			// 加载更多消息
			loadMoreMessages() {
				// 这里可以实现加载历史消息的逻辑
				console.log('加载更多消息');
			},

			// 格式化AI响应的方法增加日志
			formatAIResponse(content) {
				console.log('开始格式化AI响应:', content);
				
				// 移除可能显示的CSS样式乱码
				content = content.replace(/\d+e\d+;margin:[\s\d]+px[\s\d]+px[\s\d]+;"/g, '"');
				
				// 保持换行符
				content = content.replace(/\n/g, '<br/>');
				
				// 增强标题格式化，添加图标
				content = content.replace(/最佳旅行时间[:：]/g, '<div class="enhanced-title"><span class="title-icon">🕒</span><span class="title-text">最佳旅行时间:</span></div>');
				content = content.replace(/景点推荐[:：]/g, '<div class="enhanced-title"><span class="title-icon">🏞️</span><span class="title-text">景点推荐:</span></div>');
				content = content.replace(/美食推荐[:：]/g, '<div class="enhanced-title"><span class="title-icon">🍜</span><span class="title-text">美食推荐:</span></div>');
				content = content.replace(/住宿推荐[:：]/g, '<div class="enhanced-title"><span class="title-icon">🏨</span><span class="title-text">住宿推荐:</span></div>');
				content = content.replace(/交通指南[:：]/g, '<div class="enhanced-title"><span class="title-icon">🚗</span><span class="title-text">交通指南:</span></div>');
				content = content.replace(/旅游贴士[:：]/g, '<div class="enhanced-title"><span class="title-icon">💡</span><span class="title-text">旅游贴士:</span></div>');
				content = content.replace(/费用预算[:：]/g, '<div class="enhanced-title"><span class="title-icon">💰</span><span class="title-text">费用预算:</span></div>');
				content = content.replace(/行程安排[:：]/g, '<div class="enhanced-title"><span class="title-icon">📅</span><span class="title-text">行程安排:</span></div>');
				
				// 标准Markdown标题格式化
				content = content.replace(/###\s*(.*?)(\*\*)?(\*\*)?(\<br\/\>|\s|$)/g, '<h3 class="md-heading">$1</h3>');
				content = content.replace(/##\s*(.*?)(\<br\/\>|\s|$)/g, '<h2 class="md-heading">$2</h2>');
				content = content.replace(/#\s*(.*?)(\<br\/\>|\s|$)/g, '<h1 class="md-heading">$1</h1>');
				
				// 分隔线
				content = content.replace(/---(\<br\/\>|\s|$)/g, '<hr style="border: 0; height: 1px; background: #eee; margin: 20px 0;">');
				
				// 美化列表项，添加彩色圆点
				content = content.replace(/- ([^<]+)(?:<br\/>|$)/g, '<div class="enhanced-list-item"><span class="item-bullet"></span>$1</div>');
				
				// 高亮景点名称
				content = content.replace(/([^<:：]+)[:：](?=\s*亚洲|世界|有"|\w)/g, '<span class="spot-name">$1:</span>');
				
				// 加粗
				content = content.replace(/\*\*(.*?)\*\*/g, '<b>$1</b>');
				
				// 中文标题【】格式化
				content = content.replace(/【(.*?)】/g, '<span class="bracket-title">【$1】</span>');
				
				// 引用或强调样式
				content = content.replace(/\*(.*?)\*/g, '<i>$1</i>');
				
				// 旅游相关内容增强
				if (content.includes('行程') || content.includes('旅游') || content.includes('景点') || content.includes('住宿') || 
				    content.includes('Day') || content.includes('预算')) {
					console.log('检测到旅游相关内容，进行格式化');
					
					// 高亮价格
					content = content.replace(/￥(\d+)/g, '<span class="price-highlight">￥$1</span>');
					content = content.replace(/(\d+)元/g, '<span class="price-highlight">$1元</span>');
					content = content.replace(/¥(\d+)/g, '<span class="price-highlight">¥$1</span>');
					content = content.replace(/¥(\d+[-~]\d+)/g, '<span class="price-highlight">¥$1</span>');
					
					// 高亮时间和日程
					content = content.replace(/(Day\d+)[:：]/g, '<span class="day-highlight">$1:</span>');
					content = content.replace(/(第\d+天)[:：]/g, '<span class="day-highlight">$1:</span>');
					content = content.replace(/(上午|下午|晚上|早上|中午|傍晚)[:：]/g, '<span class="time-highlight">$1:</span>');
					
					// 高亮关键词
					content = content.replace(/(著名|必去|推荐|特色|知名)/g, '<span class="keyword-highlight">$1</span>');
					
					console.log('格式化后的内容:', content);
				}
				
				return content;
			},

			async testConnection() {
				console.log('开始测试连接');
				try {
					// 显示加载提示
					uni.showLoading({
						title: '测试连接中...'
					});
					
					// 测试WebSocket连接
					if (!this.isConnected) {
						console.log('WebSocket未连接，尝试重新连接');
						await this.startSession();
					}
					
					// 发送测试消息
					const testMessage = "测试消息：你好";
					console.log('发送测试消息:', testMessage);
					
					// 添加系统测试消息
					this.addMessage('开始连接测试...', 'system');
					
					// 测试WebSocket连接
					await this.testWebSocketConnection();
					
					// 直接发送测试消息，不设置inputMessage
					try {
						const response = await chatWithAI(this.sessionId, testMessage);
						if (response.code === 200) {
							console.log('测试消息发送成功');
						} else {
							throw new Error(response.msg || '测试消息发送失败');
						}
					} catch (error) {
						throw new Error('测试消息发送失败: ' + error.message);
					}
					
					// 隐藏加载提示
					uni.hideLoading();
					
					// 显示测试成功提示
					uni.showToast({
						title: '连接测试成功',
						icon: 'success'
					});
					
				} catch (error) {
					console.error('测试连接失败:', error);
					// 隐藏加载提示
					uni.hideLoading();
					// 显示错误提示
					uni.showToast({
						title: '测试失败',
						icon: 'error'
					});
				}
			},
			
			// WebSocket连接测试
			async testWebSocketConnection() {
				return new Promise((resolve, reject) => {
					try {
						// 检查WebSocket连接状态
						if (!this.isConnected) {
							console.log('WebSocket未连接，无法发送测试消息');
							reject(new Error('WebSocket未连接'));
							return;
						}
						
						console.log('尝试通过WebSocket发送测试消息');
						
						// 发送测试消息
						uni.sendSocketMessage({
							data: JSON.stringify({type: 'test', message: 'WebSocket测试消息'}),
							success: () => {
								console.log('WebSocket测试消息发送成功');
								this.addMessage('WebSocket测试消息已发送，等待回应...', 'system');
								// 设置超时检测，5秒内没收到回应就认为失败
								setTimeout(() => {
									resolve(); // 我们不等待回应，只测试消息是否能发出去
								}, 1000);
							},
							fail: (error) => {
								console.error('WebSocket测试消息发送失败:', error);
								this.addMessage('WebSocket测试消息发送失败', 'system');
								reject(error);
							}
						});
					} catch (error) {
						console.error('WebSocket测试过程出错:', error);
						reject(error);
					}
				});
			},
			
			// 轮询获取AI回复
			async pollForAIReply(sessionId, maxAttempts = 3, interval = 5000) {
				console.log(`开始轮询获取AI回复，最多${maxAttempts}次，间隔${interval}ms`);
				
				// 添加轮询提示消息
				this.addMessage('正在获取AI回复...', 'system');
				
				// 检查是否已有回复（通过WebSocket接收）
				const lastMessage = this.messages[this.messages.length - 1];
				if (lastMessage && lastMessage.type === 'ai' && !lastMessage.isThinking) {
					console.log('已通过WebSocket收到回复，停止轮询');
					return;
				}
				
				let attempt = 0;
				
				const poll = async () => {
					if (attempt >= maxAttempts) {
						console.log(`已达到最大轮询次数(${maxAttempts})，停止轮询`);
						// 添加轮询失败消息
						this.addMessage('获取AI回复超时，尝试从服务器直接获取回复...', 'system');
						
						// 如果轮询失败，尝试直接从服务器获取回复
						try {
							// 直接使用chatWithAI请求，可能会返回完整响应
							console.log('尝试通过直接聊天请求获取回复');
							const response = await chatWithAI(sessionId, "获取上一条回复");
							
							if (response && response.data && response.data.reply) {
								console.log('成功通过chatWithAI获取回复:', response.data.reply);
								// 如果有正在思考的消息，先移除
								if (this.messages.length > 0 && this.messages[this.messages.length - 1].isThinking) {
									this.messages.pop();
								}
								// 检查是否是旅游行程信息
								const isPlanContent = this.checkIfTravelPlanContent(response.data.reply);
								if (isPlanContent) {
									console.log('轮询检测到旅游行程信息，解析为卡片显示');
									const planData = this.parseTravelPlanContent(response.data.reply);
									this.addTravelPlanMessage(planData);
								} else {
									// 显示回复
									let formattedContent = this.formatAIResponse(response.data.reply);
									this.addMessage(formattedContent, 'ai');
								}
								
								this.isLoading = false;
								return;
							}
						} catch (error) {
							console.error('通过直接聊天请求获取回复失败:', error);
						}
						
						// 如果仍有"思考中"消息，移除它
						if (this.messages.length > 0 && this.messages[this.messages.length - 1].isThinking) {
							this.messages.pop();
							this.addMessage('获取回复失败，请重新发送消息', 'ai');
						}
						this.isLoading = false;
						return;
					}
					
					attempt++;
					console.log(`第${attempt}次轮询获取AI回复`);
					
					try {
						const response = await getLastAIReply(sessionId);
						console.log(`第${attempt}次轮询响应:`, response);
						
						if (response && response.code === 200 && response.reply) {
							console.log('轮询成功获取到AI回复:', response.reply);
							
							// 检查是否已有这条消息
							const lastMessage = this.messages[this.messages.length - 1];
							if (lastMessage && lastMessage.type === 'ai' && !lastMessage.isThinking &&
								lastMessage.content === response.reply) {
								console.log('已有此消息，不重复显示');
								return;
							}
							
							// 检查是否是旅游行程信息
							const isPlanContent = this.checkIfTravelPlanContent(response.reply);
							if (isPlanContent) {
								console.log('轮询检测到旅游行程信息，解析为卡片显示');
								const planData = this.parseTravelPlanContent(response.reply);
								this.addTravelPlanMessage(planData);
							} else {
								// 显示回复
								let formattedContent = this.formatAIResponse(response.reply);
								this.addMessage(formattedContent, 'ai');
							}
							
							this.isLoading = false;
							return;
						}
						
						// 如果未获取到回复，继续轮询
						setTimeout(poll, interval);
					} catch (error) {
						console.error(`第${attempt}次轮询出错:`, error);
						// 如果出错，继续轮询，但不计入失败次数
						setTimeout(poll, interval);
					}
				};
				
				// 开始第一次轮询
				poll();
			},

			async fetchServerResponse() {
				console.log('开始获取服务器响应');
				try {
					// 显示加载提示
					uni.showLoading({
						title: '获取服务器响应中...'
					});
					
					// 发送HTTP请求
					console.log('发送HTTP请求到服务器:', {
						sessionId: this.sessionId,
						message: '获取服务器响应',
						baseUrl,
						url: `${baseUrl}/api/ai/travel/fetchServerResponse`
					});

					const response = await fetchServerResponse(this.sessionId);
					console.log('服务器响应:', response);
					
					if (response.code === 200) {
						console.log('服务器响应获取成功');
						// 如果有正在思考的消息，先移除
						if (this.messages.length > 0 && this.messages[this.messages.length - 1].isThinking) {
							this.messages.pop();
						}
						let formattedContent = this.formatAIResponse(response.data.reply);
						this.addMessage(formattedContent, 'ai');
					} else {
						throw new Error(response.msg || '获取服务器响应失败');
					}
				} catch (error) {
					console.error('获取服务器响应失败:', error);
					uni.showToast({
						title: error.message || '获取服务器响应失败，请重试',
						icon: 'none'
					});
					this.addMessage('抱歉，获取服务器响应失败，请重试。', 'ai');
				} finally {
					this.isLoading = false;
					// 隐藏加载提示
					uni.hideLoading();
				}
			},

			// 检查是否有未接收的消息
			async checkForMissedMessages() {
				if (!this.sessionId) return;
				
				console.log('检查是否有未接收的消息');
				
				try {
					// 请求最新消息
					if (this.socketTask && this.isConnected) {
						console.log('WebSocket已连接，发送请求获取最新消息');
						this.socketTask.send({
							data: JSON.stringify({
								type: 'get_last_message',
								sessionId: this.sessionId
							}),
							success() {
								console.log('请求最新消息发送成功');
							},
							fail(error) {
								console.error('请求最新消息发送失败:', error);
							}
						});
					}
					
					// 通过HTTP接口获取最新回复
					console.log('尝试通过HTTP接口获取最新回复');
					const response = await getLastAIReply(this.sessionId);
					
					if (response && response.code === 200 && response.reply) {
						console.log('成功获取到最新回复:', response.reply);
						
						// 检查是否已有这条消息
						const lastMessage = this.messages[this.messages.length - 1];
						if (lastMessage && lastMessage.type === 'ai' && !lastMessage.isThinking &&
							lastMessage.content === response.reply) {
							console.log('已有此消息，不重复显示');
							return;
						}
						
						// 检查是否是旅游行程信息
						const isPlanContent = this.checkIfTravelPlanContent(response.reply);
						if (isPlanContent) {
							console.log('检测到旅游行程信息，解析为卡片显示');
							const planData = this.parseTravelPlanContent(response.reply);
							this.addTravelPlanMessage(planData);
						} else {
							// 显示普通回复
							let formattedContent = this.formatAIResponse(response.reply);
							this.addMessage(formattedContent, 'ai');
						}
					}
				} catch (error) {
					console.error('检查未接收消息失败:', error);
				}
			},

			// 检查是否是旅游行程信息
			checkIfTravelPlanContent(content) {
				// 检查内容是否包含旅游行程相关关键字
				const keywords = [
					'行程安排', '旅游计划', '旅行计划',
					'计划名称', '计划简介', '行程特色',
					'行程总花费', '行程总费用', '旅游地点',
					'¥', '￥', '预算', '第一天', '第二天', 
					'第三天', 'Day1', 'Day2', '第.*天'
				];
				
				// 使用正则表达式检查是否包含关键字和行程特征结构
				const contentHasKeywords = keywords.some(keyword => {
					const regex = new RegExp(keyword, 'i');
					return regex.test(content);
				});
				
				// 检查是否包含旅游格式特征（至少有3个冒号和行程日期特征）
				const hasColonFormat = (content.match(/[:：]/g) || []).length >= 3;
				const hasDayPattern = /第\s*\d+\s*天|Day\s*\d+/i.test(content);
				
				return contentHasKeywords && (hasColonFormat || hasDayPattern);
			},

			// 解析旅游行程信息
			parseTravelPlanContent(content) {
				console.log('开始解析旅游行程内容');
				
				// 初始化空的计划数据
				const planData = {
					name: '',
					description: '',
					features: '',
					price: '',
					currentDay: '1',
					city: '',
					attractions: '',
					food: '',
					arrangement: '',
					note: '',
					days: '5天4晚',
					spots: '12个地点'
				};
				
				// 提取行程名称
				const nameMatch = content.match(/计划名称[：:]\s*([^\n]+)/);
				if (nameMatch) planData.name = nameMatch[1].trim();
				
				// 如果没提取到名称，尝试其他模式
				if (!planData.name) {
					const altNameMatch = content.match(/(.*)[日游|旅行|旅游计划]/);
					if (altNameMatch) planData.name = altNameMatch[1].trim();
				}
				
				// 如果仍未提取到，使用默认值
				if (!planData.name) planData.name = '旅游计划';
				
				// 提取行程简介
				const descMatch = content.match(/计划简介[：:]\s*([^\n]+)/);
				if (descMatch) planData.description = descMatch[1].trim();
				else {
					// 尝试其他可能的简介模式
					const altDescMatch = content.match(/简介[：:]\s*([^\n]+)/);
					if (altDescMatch) planData.description = altDescMatch[1].trim();
				}
				
				// 提取行程特色
				const featuresMatch = content.match(/行程特色[：:]\s*([^\n]+)/);
				if (featuresMatch) planData.features = featuresMatch[1].trim();
				
				// 提取行程总花费
				const priceMatch = content.match(/行程总花费[：:]\s*([^\n]+)|预算[：:]\s*([^\n]+)|总花费[：:]\s*([^\n]+)|花费[：:]\s*([^\n]+)/);
				if (priceMatch) {
					planData.price = (priceMatch[1] || priceMatch[2] || priceMatch[3] || priceMatch[4]).trim();
					// 移除价格中的¥或￥符号，统一用前端显示
					planData.price = planData.price.replace(/[¥￥]/g, '');
				}
				
				// 提取当前天数
				const dayMatch = content.match(/第\s*(\d+)\s*天|Day\s*(\d+)/i);
				if (dayMatch) {
					planData.currentDay = dayMatch[1] || dayMatch[2];
				}
				
				// 提取城市/国家
				const cityMatch = content.match(/城市[：:]\s*([^\n]+)|地点[：:]\s*([^\n]+)|国家[：:]\s*([^\n]+)/);
				if (cityMatch) planData.city = (cityMatch[1] || cityMatch[2] || cityMatch[3]).trim();
				
				// 提取景点/地点
				const attractionsMatch = content.match(/地点[：:]\s*([^\n]+)|景点[：:]\s*([^\n]+)|旅游地点[：:]\s*([^\n]+)/);
				if (attractionsMatch) planData.attractions = (attractionsMatch[1] || attractionsMatch[2] || attractionsMatch[3]).trim();
				
				// 提取美食
				const foodMatch = content.match(/周边美食[：:]\s*([^\n]+)|美食[：:]\s*([^\n]+)|特色美食[：:]\s*([^\n]+)/);
				if (foodMatch) planData.food = (foodMatch[1] || foodMatch[2] || foodMatch[3]).trim();
				
				// 提取安排说明
				const arrangementMatch = content.match(/安排说明[：:]\s*([^\n]+)|安排[：:]\s*([^\n]+)|行程安排[：:]\s*([^\n]+)/);
				if (arrangementMatch) planData.arrangement = (arrangementMatch[1] || arrangementMatch[2] || arrangementMatch[3]).trim();
				
				// 提取备注信息
				const noteMatch = content.match(/备注[：:]\s*([^\n]+)/);
				if (noteMatch) planData.note = noteMatch[1].trim();
				
				// 提取总天数
				const totalDaysMatch = content.match(/(\d+)\s*天\s*(\d+)\s*晚|(\d+)\s*日\s*(\d+)\s*晚/);
				if (totalDaysMatch) {
					const days = totalDaysMatch[1] || totalDaysMatch[3];
					const nights = totalDaysMatch[2] || totalDaysMatch[4];
					planData.days = `${days}天${nights}晚`;
				}
				
				// 提取景点个数
				const spotsMatch = content.match(/(\d+)\s*个景点|(\d+)\s*个地点/);
				if (spotsMatch) {
					const count = spotsMatch[1] || spotsMatch[2];
					planData.spots = `${count}个地点`;
				}
				
				console.log('解析后的旅游行程数据:', planData);
				return planData;
			},

			// 添加旅游行程消息
			addTravelPlanMessage(planData) {
				console.log('添加旅游行程卡片消息:', planData);
				
				const message = {
					type: 'ai-plan',
					planData: planData,
					isThinking: false,
					timestamp: Date.now()
				};
				
				this.messages.push(message);
				console.log('当前消息列表:', this.messages);
				
				// 保存到本地存储
				try {
					uni.setStorageSync('chat_messages', JSON.stringify(this.messages));
					console.log('消息已保存到本地存储');
				} catch (e) {
					console.error('保存消息到本地存储失败:', e);
				}
				
				this.$nextTick(() => {
					this.scrollToBottom();
				});
			},

			async testConsoleLog() {
				console.log('开始测试控制台输出');
				try {
					// 显示加载提示
					uni.showLoading({
						title: '测试控制台输出中...'
					});
					
					// 确保有sessionId
					if (!this.sessionId) {
						console.log('sessionId不存在，先创建新会话');
						const response = await startAISession();
						if (response && response.code === 200 && response.sessionId) {
							this.sessionId = response.sessionId;
							console.log('新会话创建成功，sessionId:', this.sessionId);
						} else {
							throw new Error('创建会话失败');
						}
					}
					
					// 发送测试消息
					const testMessage = "[CONSOLE_TEST] 这是一条测试控制台输出的消息 " + new Date().toLocaleString();
					console.log('发送测试消息:', testMessage);
					
					// 添加系统测试消息
					this.addMessage('开始测试控制台输出...', 'system');
					
					// 发送消息到后端
					const response = await chatWithAI(this.sessionId, testMessage);
					console.log('测试消息发送结果:', response);
					
					if (response.code === 200) {
						// 添加成功消息
						this.addMessage('测试消息已发送到后端，请检查后端控制台输出', 'system');
					} else {
						throw new Error(response.msg || '发送测试消息失败');
					}
					
					// 隐藏加载提示
					uni.hideLoading();
					
					// 显示测试成功提示
					uni.showToast({
						title: '消息已发送',
						icon: 'success'
					});
					
				} catch (error) {
					console.error('控制台输出测试失败:', error);
					// 隐藏加载提示
					uni.hideLoading();
					// 显示错误提示
					uni.showToast({
						title: '控制台输出测试失败',
						icon: 'error'
					});
					// 添加错误消息
					this.addMessage(`控制台输出测试失败: ${error.message}`, 'system');
				}
			}
		}
	}
</script>

<style>
	@font-face {
		font-family: 'iconfont';
		src: url('//at.alicdn.com/t/font_1234567_abcdefg.eot');
	}
	
	.content {
		display: flex;
		flex-direction: column;
		height: 100vh;
		background: #e6f6ff;
		font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
		padding-top: 0; /* 移除顶部padding */
		padding-bottom: 120rpx; /* 为底部输入框留出空间 */
		box-sizing: border-box;
	}
	
	/* 底部留白 */
	.bottom-space {
		height: 120rpx;
	}
	
	/* 合并后的顶部区域 */
	.header-combined {
		display: flex;
		justify-content: space-between;
		align-items: center;
		padding: 20rpx 30rpx;
		background-color: #ffffff;
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
		z-index: 110;
		box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
	}
	
	.left-section {
		flex: 1;
		display: flex;
		align-items: center;
	}
	
	.middle-section {
		flex: 2;
		display: flex;
		flex-direction: column;
		align-items: center;
	}
	
	.right-section {
		flex: 1;
		display: flex;
		justify-content: flex-end;
		align-items: center;
		gap: 10rpx;
	}
	
	.logo-container {
		display: flex;
		align-items: center;
		justify-content: center;
		margin-bottom: 5rpx;
	}
	
	.logo-icon {
		font-size: 36rpx;
		margin-right: 10rpx;
	}
	
	.main-title {
		font-size: 36rpx;
		font-weight: bold;
		color: #3a9eeb;
	}
	
	.sub-title {
		font-size: 24rpx;
		color: #666;
	}
	
	.back-btn {
		display: flex;
		align-items: center;
		padding: 16rpx;
		border-radius: 30rpx;
		background-color: rgba(0, 153, 255, 0.08);
		transition: all 0.2s ease;
	}
	
	.back-btn:active {
		background-color: rgba(0, 153, 255, 0.15);
	}
	
	.back-icon {
		font-size: 32rpx;
		color: #0099ff;
		font-weight: bold;
		margin-right: 5rpx;
	}
	
	.back-text {
		font-size: 28rpx;
		color: #0099ff;
		font-weight: 500;
	}
	
	.test-btn {
		display: flex;
		align-items: center;
		padding: 10rpx 16rpx;
		border-radius: 30rpx;
		background-color: rgba(255, 193, 7, 0.1);
		transition: all 0.2s ease;
	}
	
	.test-btn:active {
		background-color: rgba(255, 193, 7, 0.2);
	}
	
	.test-text {
		font-size: 24rpx;
		color: #ffc107;
		font-weight: 500;
	}
	
	.console-btn {
		display: flex;
		align-items: center;
		padding: 10rpx 16rpx;
		border-radius: 30rpx;
		background-color: rgba(255, 193, 7, 0.1);
		transition: all 0.2s ease;
	}
	
	.console-btn:active {
		background-color: rgba(255, 193, 7, 0.2);
	}
	
	.console-text {
		font-size: 24rpx;
		color: #ffc107;
		font-weight: 500;
	}
	
	.new-chat-btn {
		display: flex;
		align-items: center;
		color: #0099ff;
		padding: 10rpx 16rpx;
		border-radius: 30rpx;
		background-color: rgba(0, 153, 255, 0.08);
		transition: all 0.2s ease;
	}
	
	.new-chat-btn:active {
		background-color: rgba(0, 153, 255, 0.15);
	}
	
	.new-chat-icon {
		font-size: 28rpx;
		font-weight: bold;
		margin-right: 5rpx;
		color: #0099ff;
	}
	
	.new-chat-text {
		font-size: 24rpx;
		color: #0099ff;
		font-weight: 500;
	}
	
	/* 聊天头部 */
	.chat-header {
		padding: 20rpx 30rpx;
		background-color: rgba(255, 255, 255, 0.8);
		border-bottom: 1px solid #f0f0f0;
		margin-top: 120rpx; /* 调整顶部边距，为合并后的标题栏留出空间 */
		margin-bottom: 10rpx;
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
		z-index: 90;
	}
	
	.assistant-name {
		display: flex;
		align-items: center;
		font-size: 28rpx;
		color: #333;
		font-weight: 500;
	}
	
	.dot {
		width: 12rpx;
		height: 12rpx;
		background-color: #4facfe;
		border-radius: 50%;
		margin-right: 10rpx;
	}
	
	/* 消息容器 */
	.message-container {
		flex: 1;
		margin-top: 180rpx; /* 调整顶部边距，为合并后的标题栏和聊天头部留出空间 */
		padding-bottom: 120rpx; /* 为底部输入框留出空间 */
	}
	
	/* 消息列表 */
	.message-list {
		width: 100%;
		height: calc(100vh - 400rpx); /* 调整高度 */
		padding: 20rpx;
		box-sizing: border-box;
	}
	
	/* 欢迎消息容器样式 */
	.welcome-container {
		background-color: #fff;
		border-radius: 20rpx;
		margin-bottom: 30rpx;
		overflow: hidden;
		box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.03);
	}
	
	.welcome-message {
		display: flex;
		padding: 30rpx;
	}
	
	.welcome-message .avatar {
		width: 70rpx;
		height: 70rpx;
		border-radius: 50%;
		overflow: hidden;
		margin-right: 15rpx;
		border: 2rpx solid #f5f5f5;
		flex-shrink: 0;
	}
	
	.welcome-message .message-bubble {
		background-color: transparent;
		box-shadow: none;
		padding: 0;
		color: #333;
		line-height: 1.6;
		flex: 1;
	}
	
	/* 快捷问题 */
	.quick-questions {
		padding: 20rpx;
		display: flex;
		flex-direction: column;
		gap: 16rpx;
		border-top: 1px solid rgba(0, 0, 0, 0.03);
	}
	
	.quick-question {
		background-color: #f8fbfe;
		padding: 24rpx;
		border-radius: 16rpx;
		font-size: 32rpx;
		color: #333;
		box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.03);
		display: flex;
		align-items: center;
		position: relative;
	}
	
	.dot-marker {
		width: 15rpx;
		height: 15rpx;
		background-color: #72cbff;
		border-radius: 50%;
		margin-right: 20rpx;
		flex-shrink: 0;
	}
	
	.question-text {
		flex: 1;
		font-weight: 500;
		color: #333;
	}
	
	.arrow-icon {
		width: 50rpx;
		height: 50rpx;
		display: flex;
		align-items: center;
		justify-content: center;
		border-radius: 50%;
		background-color: rgba(114, 203, 255, 0.1);
		flex-shrink: 0;
		color: #72cbff;
	}
	
	.arrow-icon text {
		color: #72cbff;
		font-size: 36rpx;
		font-weight: bold;
		line-height: 1;
	}
	
	.message-item {
		margin-bottom: 30rpx;
		animation: fadeIn 0.3s ease;
	}
	
	.message-header {
		display: flex;
		align-items: center;
		margin-bottom: 10rpx;
		padding: 0 20rpx;
	}
	
	.message-time {
		font-size: 22rpx;
		color: #999;
		margin-right: 10rpx;
	}
	
	.message-role {
		font-size: 22rpx;
		color: #666;
	}
	
	.message-content {
		display: flex;
		align-items: flex-start;
		padding: 0 20rpx;
	}
	
	.avatar {
		width: 70rpx;
		height: 70rpx;
		border-radius: 50%;
		overflow: hidden;
		margin-right: 15rpx;
		border: 2rpx solid #f5f5f5;
	}
	
	.avatar image {
		width: 100%;
		height: 100%;
	}
	
	.message-bubble {
		max-width: 70%;
		padding: 30rpx;
		border-radius: 16rpx;
		font-size: 28rpx;
		line-height: 1.6;
		position: relative;
		word-break: break-word;
	}
	
	.message-bubble rich-text {
		line-height: 1.6;
	}
	
	.message-bubble b {
		color: #0099ff;
		font-weight: 600;
	}
	
	.message-bubble span {
		display: inline-block;
		margin: 0 4rpx;
	}
	
	.user .message-content {
		flex-direction: row-reverse;
	}
	
	.user .avatar {
		margin-right: 0;
		margin-left: 15rpx;
	}
	
	.user .message-bubble {
		background: linear-gradient(135deg, #72cbff 0%, #5bb8eb 100%);
		color: #fff;
		border-radius: 16rpx;
		padding: 30rpx;
		line-height: 1.6;
	}
	
	.ai .message-bubble {
		background-color: #fff;
		color: #333;
		box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.03);
		padding: 30rpx;
		line-height: 1.6;
		border-radius: 16rpx;
	}
	
	.ai .message-bubble rich-text {
		color: #333;
		line-height: 1.6;
	}
	
	.ai .message-bubble rich-text ol,
	.ai .message-bubble rich-text ul {
		padding-left: 40rpx;
		margin: 10rpx 0;
	}
	
	.ai .message-bubble rich-text ol li,
	.ai .message-bubble rich-text ul li {
		margin: 10rpx 0;
	}
	
	/* 思考中动画 */
	.thinking-dots {
		display: flex;
		align-items: center;
		height: 40rpx;
	}
	
	.thinking-dots text {
		font-size: 40rpx;
		animation: thinking 1s infinite;
		margin: 0 2rpx;
		color: #666;
	}
	
	.thinking-dots text:nth-child(2) {
		animation-delay: 0.2s;
	}
	
	.thinking-dots text:nth-child(3) {
		animation-delay: 0.4s;
	}
	
	@keyframes thinking {
		0%, 100% { 
			opacity: 0.3;
			transform: translateY(0);
		}
		50% { 
			opacity: 1;
			transform: translateY(-4rpx);
		}
	}
	
	/* 输入区域 */
	.input-area {
		display: flex;
		padding: 15rpx 20rpx;
		background-color: #ffffff;
		border-top: 1px solid rgba(0, 0, 0, 0.05);
		position: fixed;
		bottom: 0;
		left: 0;
		right: 0;
		z-index: 100;
	}
	
	.message-input {
		flex: 1;
		height: 70rpx;
		background-color: #f5f7fa;
		border-radius: 35rpx;
		padding: 0 30rpx;
		font-size: 28rpx;
		color: #333;
	}
	
	.send-btn {
		width: 140rpx;
		height: 70rpx;
		background-color: #72cbff;
		color: #ffffff;
		border-radius: 35rpx;
		margin-left: 15rpx;
		font-size: 28rpx;
		display: flex;
		align-items: center;
		justify-content: center;
		padding: 0;
	}
	
	.send-btn:active {
		background-color: #5bb8eb;
	}
	
	.send-btn[disabled] {
		background-color: #cccccc;
		color: #ffffff;
	}
	
	@keyframes fadeIn {
		from { 
			opacity: 0;
			transform: translateY(10rpx);
		}
		to { 
			opacity: 1;
			transform: translateY(0);
		}
	}

	/* 系统消息样式 */
	.system .message-bubble {
		background-color: rgba(0, 0, 0, 0.05);
		color: #666;
		text-align: center;
		font-size: 24rpx;
		padding: 10rpx 20rpx;
		margin: 20rpx auto;
		max-width: 80%;
		border-radius: 30rpx;
	}

	.system .avatar {
		display: none;
	}

	.system .message-header {
		justify-content: center;
	}
	
	/* 旅行计划卡片样式 */
	.travel-plan-card {
		background-color: #fff;
		border-radius: 20rpx;
		overflow: hidden;
		box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
		width: 100%;
		margin: 20rpx 0;
	}
	
	.travel-plan-header {
		padding: 20rpx;
		display: flex;
		justify-content: center;
		background-color: #f8f8f8;
		border-bottom: 1px solid #eee;
	}
	
	.plan-logo text {
		font-size: 32rpx;
		font-weight: bold;
		color: #4cd964;
	}
	
	.travel-plan-basic {
		padding: 30rpx;
		background-color: #fff;
		border-bottom: 1px solid rgba(0, 0, 0, 0.05);
	}
	
	.travel-plan-title {
		margin-bottom: 20rpx;
	}
	
	.travel-plan-title text {
		font-size: 36rpx;
		font-weight: bold;
		color: #333;
	}
	
	.travel-plan-desc {
		margin-bottom: 20rpx;
		color: #666;
		line-height: 1.5;
	}
	
	.travel-plan-feature {
		margin-bottom: 20rpx;
		color: #333;
		line-height: 1.5;
	}
	
	.travel-plan-price {
		font-weight: bold;
		color: #72cbff;
		font-size: 32rpx;
	}
	
	.travel-plan-price text:last-child {
		font-size: 24rpx;
		color: #999;
		margin-left: 10rpx;
		font-weight: normal;
	}
	
	.travel-plan-schedule {
		padding: 30rpx;
		background-color: #fff;
		display: flex;
		align-items: center;
		border-bottom: 1px solid #f5f5f5;
	}
	
	.calendar-indicator {
		background-color: #ff6b6b;
		color: #fff;
		width: 60rpx;
		height: 80rpx;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		border-radius: 6rpx;
		margin-right: 20rpx;
	}
	
	.calendar-indicator .month {
		font-size: 20rpx;
		line-height: 1;
	}
	
	.calendar-indicator .day {
		font-size: 32rpx;
		font-weight: bold;
		line-height: 1.2;
	}
	
	.schedule-title {
		font-size: 34rpx;
		font-weight: bold;
		color: #333;
	}
	
	.day-indicator {
		display: flex;
		align-items: center;
		padding: 20rpx 30rpx;
		background-color: #f8fbff;
	}
	
	.pin-icon {
		font-size: 36rpx;
		margin-right: 10rpx;
		color: #72cbff;
	}
	
	.day-text {
		font-size: 32rpx;
		color: #72cbff;
		font-weight: bold;
	}
	
	.travel-details {
		padding: 20rpx 30rpx;
		background-color: #fff;
	}
	
	.detail-item {
		margin-bottom: 20rpx;
		display: flex;
	}
	
	.detail-label {
		color: #72cbff;
		font-size: 28rpx;
		font-weight: bold;
		width: 180rpx;
		flex-shrink: 0;
	}
	
	.detail-value {
		color: #333;
		font-size: 28rpx;
		line-height: 1.5;
		flex: 1;
	}
	
	.travel-footer {
		padding: 20rpx 30rpx;
		background-color: #fff;
		display: flex;
		justify-content: space-around;
		border-top: 1px solid #f0f0f0;
	}
	
	.footer-item {
		text-align: center;
		background-color: #f8f8f8;
		padding: 10rpx 20rpx;
		border-radius: 30rpx;
	}
	
	.footer-item text {
		font-size: 24rpx;
		color: #666;
	}
	
	.travel-note {
		padding: 20rpx 30rpx;
		background-color: #f8fbff;
		border-top: 1px solid #f0f0f0;
	}
	
	.note-label {
		color: #72cbff;
		font-weight: bold;
		font-size: 28rpx;
		margin-right: 10rpx;
	}
	
	.note-content {
		color: #666;
		font-size: 28rpx;
		line-height: 1.5;
	}

	/* 格式化样式 */
	.md-heading {
		color: #0077e6;
		font-weight: bold;
		margin: 20rpx 0 10rpx 0;
	}

	h1.md-heading {
		font-size: 36rpx;
		margin: 24rpx 0 12rpx 0;
	}

	h2.md-heading {
		font-size: 32rpx;
		margin: 20rpx 0 10rpx 0;
	}

	h3.md-heading {
		font-size: 30rpx;
		margin: 16rpx 0 8rpx 0;
	}

	.enhanced-title {
		display: flex;
		align-items: center;
		margin: 30rpx 0 20rpx 0;
		background-color: #f8fbff;
		padding: 16rpx 20rpx;
		border-radius: 10rpx;
	}

	.title-icon {
		font-size: 36rpx;
		margin-right: 10rpx;
		line-height: 1;
	}

	.title-text {
		font-size: 32rpx;
		color: #0077e6;
		font-weight: bold;
	}

	.enhanced-list-item {
		display: flex;
		align-items: flex-start;
		margin: 16rpx 0;
		padding-left: 10rpx;
	}

	.item-bullet {
		width: 12rpx;
		height: 12rpx;
		background-color: #72cbff;
		border-radius: 50%;
		margin: 14rpx 15rpx 0 0;
		flex-shrink: 0;
	}

	.spot-name {
		color: #0077e6;
		font-weight: bold;
	}

	.bracket-title {
		color: #0077e6;
		font-weight: bold;
	}

	.price-highlight {
		color: #ff6b6b;
		font-weight: bold;
	}

	.day-highlight {
		color: #0099ff;
		font-weight: bold;
	}

	.time-highlight {
		color: #0099ff;
		font-weight: bold;
	}

	.keyword-highlight {
		color: #ff9500;
		font-weight: bold;
	}
</style> 