<template>
	<view class="page" :style="{'min-height':h+'px', 'padding-top':mt+'px'}">
		<u-navbar title="创衡正念企业教练AI智能体" bgColor="#E9F4F6" :titleStyle="{'font-size':'32rpx','font-weight':'bold','color':'#002846'}">
			<view class="u-nav-slot" slot="left" style="display: flex;background-color: transparent;">
				<image src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/06/16/ef50e3e8-d0f9-41dd-a4ec-546b157a1de9.png" style="width: 45rpx;height: 45rpx;" @tap="toBack"></image>
				<!-- <image src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/06/16/e536bf8e-3b33-4ea8-b60b-7154c6353bec.png" style="width: 42rpx;height: 42rpx;margin-left: 40rpx;" @tap="startNewDialog"></image> -->
			</view>
		</u-navbar>
		<template v-if="dialogList.length===0">
			<view class="welcome">
				<image src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/06/16/5292af4c-977b-4620-a4e4-4aadcd5ad092.png"></image>
				<p>Hi，我是大创教练～</p>
				<p class="tip">欢迎与我探讨任何关于团队教练、PERILL团队发展动态评估报告或团队发展的话题。我的对话能力正在进化中，希望能给你的团队教练辅导一些启发~</p>
			</view>
		</template>
		<template v-else>
			<view class="dialogs container" ref="messageContainer">
				<view class="d_answer init">
					<view class="da_top adfac">
						<image src="@/static/logo.png"></image>
						<text>大创教练</text>
					</view>
					<view class="da_content">Hi，任何关于团队、分析报告、教练的问题，你都可以向我提问～</view>
				</view>
				<view v-for="(item,index) in dialogList" :key="index">
					<view class="d_question">
						<view class="dq_text">{{ item.question }}</view>
					</view>
					<view class="d_answer">
						<view class="da_top adfac">
							<image src="@/static/logo.png"></image>
							<text>大创教练</text>
						</view>
						<view class="da_content">
							<template v-if="item.think">
								<view class="dac_think adfac">
									<image src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/07/07/13c5dd16-2032-464a-8b1c-2722d201cfe2.gif"></image>
									<text>正在思考中</text>
								</view>
							</template>
							<template v-else>
								<view style="font-size: 30rpx;color: #002846;line-height: 54rpx;">
									<u-parse :content="item.answer"></u-parse>
								</view>
							</template>
							<view class="dc_btns adfacjb" v-if="item.answer">
								<view class="db_l">
									<image :src="item.copy?require('@/static/copy_active.png'):require('@/static/copy.png')" @tap="toCopy(item,index)"></image>
									<image :src="item.upvote?require('@/static/upvote_active.png'):require('@/static/upvote.png')" @tap="toUpvote(item,index)"></image>
									<!-- <image :src="item.comment?require('@/static/comment_active.png'):require('@/static/comment.png')" @tap="toComment(item,index)"></image> -->
								</view>
								<view class="db_r">
								<!-- 	<image :src="item.share?require('@/static/share_active.png'):require('@/static/share.png')" @tap="toShare(item,index)"></image> -->
								</view>
							</view>
						</view>
					</view>
				</view>
			</view>
		</template>
		<view class="ask_box" :style="{'bottom':fixBottom+'px'}">
			<view class="ask">
				<view class="a_inp">
					<view class="ai_l">
						<u-textarea v-model="question" placeholder="请输入你的问题" placeholder-style="font-size:30rpx;color:#95A5B1;" @confirm="sendQuestion" autoHeight :showConfirmBar="false" :adjustPosition="false" maxlength="999999"></u-textarea>
					</view>
					<view class="ai_r">
						<image @tap="sendQuestion" :src="imgBase+'dialog_send.png'"></image>
					</view>
				</view>
			</view>
			<view class="ask_memo">本服务为AI生成内容，结果仅供参考</view>
		</view>
		<u-modal :show="commentShow" title="评论" @confirm="commentConfirm" @cancel="commentCancel" @close="commentCancel" :showCancelButton="true">
			<u-textarea v-model="content" placeholder="对于我们的回答你是否不满意，你有更好的答案建议吗？请在此输入."></u-textarea>
		</u-modal>
	</view>
</template>

<script>
	var timer = null;
	let requestTask = null;
	import { BaseApi } from '../http/baseApi.js'
	import * as TextEncoding from "text-encoding-shim";
	export default {
		data(){
			return {
				isDialog:false,
				retryCount: 3, // 最大重试次数
				currentRetry: 0, // 当前重试次数
				isRequesting: false, // 请求状态锁
				question:'',
				streamingResponse:'',
				receivedData:'',
				dialogList:[],
				windex:0,
				commentShow:false,
				content:'',
				cindex:'',
				chzq:false,
				lwss:false,
				fixBottom: 0
			}
		},
		onReady() {
		    uni.onKeyboardHeightChange(res => {
		      this.fixBottom = res.height||0;
		    });
		},
		onUnload() {
		    uni.offKeyboardHeightChange();
			this.fixBottom = 0;
		},
		methods:{
			toBack(){
				uni.reLaunch({
					url:'/pages/home'
				})
			},
			startNewDialog(){
				clearInterval(timer)
				this.dialogList = [];
				this.question = '';
				this.streamingResponse = '';
			},
			// 封装带重试机制的请求方法
			async sendRequestWithRetry() {
				if (this.isRequesting) return;
				this.isRequesting = true;
				this.currentRetry = 0;
				try {
					await this._executeRequest();
				} catch (error) {
					  this.$showToast('请求失败，请稍后重试')
				} finally {
					this.isRequesting = false;
				}
			},
			_executeRequest2(){
				return new Promise((resolve, reject) => {
					this.$api.post('/core/chat/sendChatMessageStream',{query:this.question},false).then(res=>{
						if(res.data.code!==0) return this.$showToast(res.data.msg)
						let answer = this.dialogList[this.dialogList.length-1].answer+res.data.data;
						this.$set(this.dialogList[this.dialogList.length-1],'answer',answer);
						this.$set(this.dialogList[this.dialogList.length-1],'think',false);
						setTimeout(()=>{
							this.scrollToBottom();
						},100)
						resolve()
					})
				})
			},
			// 实际执行请求的方法
			_executeRequest() {
				return new Promise((resolve, reject) => {
					requestTask = uni.request({
						url: `${BaseApi}/core/chat/sendChatMessageStream`,
						method: 'POST',
						timeout: 10000,
						data:{ 
							query: this.question,
							identity:'被教练者',
						},
						header: {
						  'Content-Type': 'application/json',
						  'token': uni.getStorageSync('token') || ''
						},
						enableChunked: true, // 启用流式接收
						responseType:'text',
						success: (res) => {
							if (res.statusCode === 200) {
								this._handleSuccess(res.data);
								resolve();
							} else {
								this._handleError(`状态码异常: ${res.statusCode}`, resolve, reject);
							}
						},
						fail: (err) => {
							this._handleError(err.errMsg, resolve, reject);
						},
						complete: (com) => {
							console.log('请求完成',com)
						}
					});
					
					requestTask.onChunkReceived(async (res) => {
						const uint8Array = new Uint8Array(res.data);
						const decoder = new TextEncoding.TextDecoder("utf-8");
						const decodedString = decoder.decode(uint8Array);
						try {
							let newtext = decodedString.replaceAll('data:','').replaceAll(':keepAlive','');
							let ntArr = newtext.split('\n\n');
							if(ntArr.length){
								ntArr.forEach(n=>{
									if(!n.trim()) return
									let nj = JSON.parse(n);
									if(nj.event=='message'){
										let answer = this.dialogList[this.dialogList.length-1].answer+nj.answer?.replace(/(\r\n|\n|\r)+/g, '<br>');
										this.$set(this.dialogList[this.dialogList.length-1],'answer',answer);
										this.$set(this.dialogList[this.dialogList.length-1],'id',nj.id);
										this.$set(this.dialogList[this.dialogList.length-1],'task_id',nj.task_id);
										this.$set(this.dialogList[this.dialogList.length-1],'message_id',nj.message_id);
										this.$set(this.dialogList[this.dialogList.length-1],'conversation_id',nj.conversation_id);
										this.$set(this.dialogList[this.dialogList.length-1],'think',false);
									}
								})
								setTimeout(()=>{
									this.scrollToBottom();
								},100)
							}
						} catch (e) {
							console.error('解析失败', e, '原始数据:', decodedString);
						}
					});
				});
			},
			// 成功处理
			_handleSuccess(data) {
				if (data) {
				  this.streamingResponse += data;
				}
				this.currentRetry = 0; // 重置重试计数器
			},
			// 错误处理
			_handleError(errorMsg, resolve, reject) {
				if (this._shouldRetry(errorMsg)) {
					this.currentRetry++;
					setTimeout(() => {
						this._executeRequest().then(resolve).catch(reject);
					}, this._getRetryDelay());
				} else {
					reject(errorMsg);
				}
			},
			// 判断是否需要重试
			_shouldRetry(errorMsg) {
				const retryableErrors = [
					'timeout', 
					'request:fail', 
					'Network Error'
				];
				return this.currentRetry < this.retryCount && retryableErrors.some(e => errorMsg.includes(e));
			},
			// 获取指数退避延迟时间
			_getRetryDelay() {
				return Math.min(1000 * Math.pow(2, this.currentRetry), 10000);
			},
			sendQuestion(){
				if(!this.question) return this.$showToast('请输入你的问题');
				if(!this.isLogin()) return
				let qa = {
					question:JSON.parse(JSON.stringify(this.question)),
					answer:'',
					copy:false,
					upvote:false,
					comment:'',
					share:false,
					think:true
				}
				this.dialogList = [...this.dialogList,...[qa]];
				this.$nextTick(()=>{
					this.scrollToBottom();
					this.sendRequestWithRetry();
					this.question = '';
				})
			},
			// 滚动到底部
			scrollToBottom() {
				this.$nextTick(()=>{
					this.$nextTick(()=>{
						uni.pageScrollTo({
							scrollTop:99999,
							duration:300
						})
					})
				})
			},
			toCopy(item,index){
				uni.setClipboardData({
					data:item.answer,
					success: (res) => {
						this.$showToast('复制成功');
					},
					fail: (err) => {
						this.$showToast('复制失败');
					}
				})
			},
			toUpvote(item,index){
				this.$set(this.dialogList[index],'upvote',!this.dialogList[index].upvote);
			},
			toComment(item,index){
				this.cindex = index;
				this.commentShow = true;
			},
			toShare(item,index){
				this.$set(this.dialogList[index],'share',!this.dialogList[index].share);
			},
			commentConfirm(){
				this.$set(this.dialogList[this.cindex],'comment',this.content);
				this.commentShow = false;
			},
			commentCancel(){
				this.content = '';
				this.commentShow = false;
			},
			changeChzq(){
				this.chzq = !this.chzq;
			},
			changeLwss(){
				this.lwss = !this.lwss;
			},
		}
	}
</script>

<style scoped lang="scss">
	::v-deep .u-textarea{
		border: none !important;
		padding: 0 !important;
	}
	::v-deep .u-textarea textarea{
		min-height: 64rpx !important;
		font-size: 28rpx;
		color: #002846;
	}
	
	.page{
		background: url('https://gitee.com/hw_0302/chuang-heng-wechat-images/raw/master/dialog_bg.png') no-repeat;
		background-size: 100% 100%;
		padding: 0 30rpx 240rpx;
		box-sizing: border-box;
		
		.welcome{
			margin-top: 259rpx;
			padding: 0 34rpx;
			image{
				width: 88rpx;
				height: 87rpx;
				margin-left: 20rpx;
			}
			p{
				font-family: PingFang-SC, PingFang-SC;
				font-weight: bold;
				font-size: 36rpx;
				color: #002846;
				line-height: 36rpx;
				margin-top: 36rpx;
				&.tip{
					font-family: PingFangSC, PingFang SC;
					font-weight: 400;
					font-size: 30rpx;
					color: #667E90;
					line-height: 40rpx;
					margin-top: 20rpx;
				}
			}
		}
	
		.dialogs{
			width: 100%;
			padding-top: 34rpx;
			box-sizing: border-box;
			overflow-y: auto;
			.d_answer{
				margin-top: 40rpx;
				&.init{
					margin-top: 0;
				}
				.da_top{
					image{
						width: 48rpx;
						height: 48rpx;
					}
					text{
						font-family: PingFang-SC, PingFang-SC;
						font-weight: bold;
						font-size: 30rpx;
						color: #002846;
						line-height: 48rpx;
						margin-left: 20rpx;
					}
				}
				.da_content{
					padding: 30rpx 32rpx;
					margin-top: 20rpx;
					background: #FFFFFF;
					color: #002846;
					border-radius: 4rpx 24rpx 24rpx 24rpx;
					font-size: 30rpx;
					.dac_think{
						image{
							width: 60rpx;
							height: 60rpx;
						}
						text{
							font-size: 30rpx;
							margin-left: 10rpx;
						}
					}
					.dc_btns{
						margin-top: 44rpx;
						image{
							width: 48rpx;
							height: 48rpx;
						}
						.db_l{
							image{
								margin-right: 40rpx;
							}
						}
					}
				}
			}
			.d_question{
				margin-top: 40rpx;
				display: flex;
				justify-content: flex-end;
				.dq_text{
					background: #33A7A7;
					border-radius: 24rpx 4rpx 24rpx 24rpx;
					font-family: PingFangSC, PingFang SC;
					font-weight: 400;
					font-size: 30rpx;
					color: #FFFFFF;
					line-height: 48rpx;
					// text-align: right;
					padding: 26rpx 30rpx;
				}
			}
		}
		.ask_box{
			width: 100%;
			min-height: 176rpx;
			padding: 0 30rpx 60rpx;
			position: fixed;
			left: 0;
			box-sizing: border-box;
			background: #F6F6F6;
			
			.ask_memo{
				font-family: PingFangSC, PingFang SC;
				font-weight: 400;
				font-size: 24rpx;
				color: #b1b1b1;
				line-height: 34rpx;
				text-align: center;
				margin-top: 16rpx;
			}
		}
	
		.ask{
			min-height: 116rpx;
			background: #FFFFFF;
			border-radius: 24rpx;
			border: 2rpx solid #F0F2F8;
			padding: 24rpx;
			box-sizing: border-box;
			.a_inp{
				display: flex;
				align-items: flex-end;
				max-height: 300rpx;
				overflow-y: auto;
				.ai_l{
					width: calc(100% - 64rpx);
					padding-right: 20rpx;
					box-sizing: border-box;
				}
				.ai_r{
					width: 64rpx;
					image{
						width: 64rpx;
						height: 64rpx;
					}
				}
			}
		}
	}
</style>