<template>
	<view class="container">
		<!-- 输入区域 -->
		<view class="input-area">
			<input v-model="question" placeholder="请输入问题" :disabled="isLoading"
				@confirm="startStreamAnswer(question)" />
			<button @click="startStreamAnswer(question)" :disabled="isLoading || !question.trim()"
				:class="{ 'loading': isLoading }">
				{{ isLoading ? '回答中...' : '发送' }}
			</button>
		</view>

		<!-- 回答区域 -->
		<view class="answer-area" v-if="answer || isLoading">
			<view class="answer-content">
				<text>{{ displayText }}</text>
				<!-- 打字机光标 -->
				<text v-if="!isComplete" class="cursor">|</text>
			</view>

			<!-- 加载状态 -->
			<view v-if="isLoading" class="loading-status">
				<view class="loading-dots">
					<text>.</text>
					<text>.</text>
					<text>.</text>
				</view>
			</view>

			<!-- 错误提示 -->
			<view v-if="error" class="error-message">
				<text>{{ error }}</text>
				<button @click="startStreamAnswer(question)" class="retry-btn">
					重试
				</button>
			</view>
		</view>
	</view>
</template>
<script>
	// 在页面或组件中
	export default {
		data() {
			return {
				question: '', // 用户输入的问题:给我一段200字的数学老师的个人介绍
				answer: '', // 完整的回答
				displayText: '', // 用于显示的文本
				isComplete: false, // 是否完成
				isLoading: false, // 是否正在加载
				error: null, // 错误信息
				retryCount: 0, // 重试次数
				maxRetries: 3, // 最大重试次数
				timer: null, // 定时器
				lastResponseTime: 0, // 最后一次响应时间
				timeout: 30000, // 超时时间（30秒）
				typingSpeed: 50, // 打字速度（毫秒）
				socketTask: null, // WebSocket 连接
			}
		},
		methods: {
			// 开始流式请求
			async startStreamAnswer(content) {
				if (!content.trim()) {
					uni.showToast({
						title: '请输入问题',
						icon: 'none'
					});
					return;
				}

				// 重置状态
				this.resetState();
				this.isLoading = true;

				try {
					const response = await fetch(this.$apiHost + '/Work/streamAnswer?content=' + encodeURIComponent(content));
					console.log("response",response);
					const reader = response.body.getReader();
					const decoder = new TextDecoder();

					while (true) {
						const { value, done } = await reader.read();
						if (done) break;
						
						const text = decoder.decode(value);
						if (text === '[DONE]') {
							this.completeAnswer();
							break;
						}
						
						// 直接更新显示文本
						this.displayText += text;
						this.answer += text;
						this.retryCount = 0;
						this.lastResponseTime = Date.now();
					}
				} catch (error) {
					this.handleError(error);
				}
			},

			// 重置状态
			resetState() {
				this.answer = '';
				this.displayText = '';
				this.isComplete = false;
				this.error = null;
				this.retryCount = 0;
				this.lastResponseTime = Date.now();
				this.stopStreamAnswer();
			},

			// 处理错误
			handleError(error) {
				console.error('请求错误:', error);

				if (this.retryCount < this.maxRetries) {
					this.retryCount++;
					this.retryRequest();
				} else {
					this.error = '请求失败，请稍后重试';
					this.isLoading = false;
					uni.showToast({
						title: this.error,
						icon: 'none'
					});
				}
			},

			// 重试请求
			retryRequest() {
				uni.showToast({
					title: `正在重试 (${this.retryCount}/${this.maxRetries})`,
					icon: 'none'
				});

				setTimeout(() => {
					this.startStreamAnswer(this.question);
				}, 1000 * this.retryCount);
			},

			// 完成回答
			completeAnswer() {
				this.isComplete = true;
				this.isLoading = false;
				this.stopStreamAnswer();
			},

			// 停止请求
			stopStreamAnswer() {
				if (this.timer) {
					clearTimeout(this.timer);
					this.timer = null;
				}
				if (this.socketTask) {
					this.socketTask.close();
					this.socketTask = null;
				}
			},

			// 检查超时
			checkTimeout() {
				if (Date.now() - this.lastResponseTime > this.timeout) {
					this.handleError(new Error('请求超时'));
				}
			}
		},
		// 组件创建时
		created() {
			console.log('组件已创建');
			// 启动超时检查
			this.timer = setInterval(() => {
				if (this.isLoading) {
					this.checkTimeout();
				}
			}, 1000);
		},
		// 组件销毁时
		beforeDestroy() {
			this.stopStreamAnswer();
		}
	}
</script>
<style scoped lang="scss">
	.container {
		padding: 20rpx;
	}

	.input-area {
		display: flex;
		margin-bottom: 20rpx;
		gap: 20rpx;

		input {
			flex: 1;
			height: 100rpx;
			padding: 20rpx;
			border: 1px solid #ddd;
			border-radius: 8rpx;
			background-color: #fff;
		}

		button {
			padding: 0 30rpx;
			background-color: #007AFF;
			color: white;
			border-radius: 8rpx;

			&.loading {
				background-color: #ccc;
			}
		}
	}

	.answer-area {
		padding: 20rpx;
		background-color: #f5f5f5;
		border-radius: 10rpx;
		min-height: 200rpx;
	}

	.answer-content {
		line-height: 1.6;
	}

	.cursor {
		display: inline-block;
		animation: blink 1s infinite;
	}

	.loading-status {
		margin-top: 20rpx;
		text-align: center;
	}

	.loading-dots {
		display: inline-block;

		text {
			animation: dots 1.5s infinite;
			opacity: 0;

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

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

	.error-message {
		margin-top: 20rpx;
		color: #ff4d4f;
		text-align: center;
	}

	.retry-btn {
		margin-top: 10rpx;
		padding: 10rpx 20rpx;
		background-color: #ff4d4f;
		color: white;
		border-radius: 6rpx;
	}

	@keyframes blink {

		0%,
		100% {
			opacity: 1;
		}

		50% {
			opacity: 0;
		}
	}

	@keyframes dots {

		0%,
		100% {
			opacity: 0;
		}

		50% {
			opacity: 1;
		}
	}
</style>