<template>
	<view class="page" :style="{'min-height':h+'px', 'padding-top':mt+'px'}">
		<u-navbar title="对话" bgColor="#F6F6F8" :titleStyle="{'font-size':'32rpx','font-weight':'bold'}">
			<view class="u-nav-slot" slot="left" style="display: flex;background-color: transparent;">
				<image src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/09/10/2f7cc90a-848c-4369-b573-4448125591a9.png" style="width: 45rpx;height: 45rpx;" @tap="toBack"></image>
				<!-- <image src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/09/10/3580b8d2-8ddb-4385-8516-fb6f47ce5fea.png" style="width: 42rpx;height: 42rpx;margin-left: 40rpx;" @tap="startNewDialog"></image> -->
				<image src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/09/10/cb27247a-8924-4ea7-a750-238ec9debd28.png" style="width: 42rpx;height: 42rpx;margin-left: 40rpx;" @tap="startNewDialog"></image>
			</view>
		</u-navbar>
		<template v-if="dialogList.length===0">
			<div class="welcome">
				<image src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/09/10/09ed81ea-ab7c-457b-a128-1d0ed43aaffd.png"></image>
				<p>Hi，很高兴见到你～</p>
				<p class="tip">我可以帮你读语文，写作各种创意内容，请把你的任务交给我吧～ </p>
			</div>
		</template>
		<template v-else>
			<div class="dialogs container" ref="messageContainer">
				<div class="d_answer init">
					<div class="da_top adfac">
						<image src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/09/10/09ed81ea-ab7c-457b-a128-1d0ed43aaffd.png"></image>
						<text>AI智能终端</text>
					</div>
					<div class="da_content">Hi，我可以帮你解答问题，写作各种创意内容，请把你的任务交给我吧～～</div>
				</div>
				<div v-for="(item,index) in dialogList" :key="index">
					<div class="d_question">
						<div class="dq_text">{{ item.question }}</div>
					</div>
					<div class="d_answer">
						<div class="da_top adfac">
							<image src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/09/10/09ed81ea-ab7c-457b-a128-1d0ed43aaffd.png"></image>
							<text>AI智能终端</text>
						</div>
						<div 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>
								<u-parse :content="item.answer" style="font-size: 28rpx;line-height: 54rpx;color: #252525;"></u-parse>
							</template>
							<div class="dc_btns adfacjb" v-if="item.answer">
								<div 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>
								</div>
								<div class="db_r">
									<image :src="item.share?require('@/static/share_active.png'):require('@/static/share.png')" @tap="toShare(item,index)"></image>
								</div>
							</div>
						</div>
					</div>
				</div>
			</div>
		</template>
		<div class="ask_box" :style="{'bottom':fixBottom+'px'}">
			<div class="ask">
				<div class="a_inp">
					<div class="ai_l">
						<u-textarea v-model="question" placeholder="请输入您的问题" autoHeight :showConfirmBar="false" :adjustPosition="false" maxlength="999999"></u-textarea>
					</div>
					<div class="ai_r">
						<image @tap="sendQuestion" src="https://transcend.ringzle.com/xiaozhi-app/profile/2025/09/10/a4a2718d-733e-467a-8bc2-7dc1548d2767.png"></image>
					</div>
				</div>
			</div>
			<div class="ask_memo">本服务为AI生成内容，结果仅供参考</div>
		</div>
		<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";
	import { webSocketConnect } from '@/common/xiaoZhiConnect.js';
	export default {
		data(){
			return {
				question:'',
				dialogList:[],
				commentShow:false,
				content:'',
				cindex:'',
				chzq:false,
				lwss:false,
				fixBottom: 0,
				// 对话
				config: {
					deviceMac: '',
					deviceName: '小智AI设备',
					clientId: 'uniapp_xiaozhi_client',
					token: 'xiaozhi-ai',
					otaUrl: 'http://i.ringzle.com:8002/xiaozhi/ota/',
					serverUrl: 'ws://i.ringzle.com:8000/xiaozhi/v1/'
				},
				isConnected: false,
				textMessage: '',
				socketTask: null,
			}
		},
		computed: {
			displayMac() {
				return this.config.deviceMac;
			},
			displayClient() {
				return this.config.clientId;
			}
		},
		onReady() {
		    uni.onKeyboardHeightChange(res => {
		      this.fixBottom = res.height||0;
		    });
		},
		onLoad(option) {
			this.config.deviceMac = option?.deviceMac;
			this.connectToServer();
		},
		onUnload() {
			this.disconnectFromServer();
		    uni.offKeyboardHeightChange();
			this.fixBottom = 0;
		},
		methods:{
			async connectToServer() {
				if (this.socketTask) return;
				console.log('开始连接流程...');
				const task = await webSocketConnect(
					this.config.otaUrl,
					this.config.serverUrl,
					this.config
				);
			
				if(task) {
					this.socketTask = task;
					this.setupSocketListeners();
				}
			},
			setupSocketListeners() {
				this.socketTask.onOpen(() => {
					this.isConnected = true;
					console.log('WebSocket连接已打开', 'success');
					this.sendHelloMessage();
				});
			
				this.socketTask.onClose(() => {
					this.isConnected = false;
					console.log('WebSocket连接已关闭', 'info');
					this.socketTask = null;
				});
			
				this.socketTask.onError((err) => {
					this.isConnected = false;
					console.log(`WebSocket错误: ${JSON.stringify(err)}`, 'error');
				});
			
				this.socketTask.onMessage((res) => {
					if (typeof res.data === 'string') {
						this.handleTextMessage(res.data);
					} else {
						this.handleBinaryMessage(res.data);
					}
				});
			},
			disconnectFromServer() {
				if (this.socketTask) {
					this.socketTask.close({
						code: 1000,
						reason: 'manual disconnection'
					});
					console.log('手动断开连接', 'info');
				}
			},
			sendSocketMessage(data) {
				if (!this.isConnected || !this.socketTask) {
					console.log('无法发送消息，连接未建立', 'error');
					return;
				}
				uni.sendSocketMessage({
					data: data,
					fail: (err) => {
						console.log(`发送消息失败: ${JSON.stringify(err)}`, 'error');
					}
				});
			},
			sendHelloMessage() {
				const helloMessage = {
					type: 'hello',
					device_id: this.config.deviceMac,
					device_name: this.config.deviceName,
					device_mac: this.config.deviceMac,
					token: this.config.token,
					features: { mcp: true }
				};
				console.log('发送hello握手消息', 'info');
				this.sendSocketMessage(JSON.stringify(helloMessage));
			},
			addConversationMessage(text, isUser = false) {
				console.log(text,isUser);
				text = text+'<br>'
				if(!isUser){
					let answer = this.dialogList[this.dialogList.length-1].answer+text?.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],'think',false);
					setTimeout(()=>{
						this.scrollToBottom();
					},100)
				}
			},
			sendTextMessage() {
				const message = this.question.trim();
				if (!message) return;
				const listenMessage = {
					type: 'listen',
					mode: 'manual',
					state: 'detect',
					text: message
				};
				this.sendSocketMessage(JSON.stringify(listenMessage));
				this.addConversationMessage(message, true);
				console.log(`发送文本: ${message}`, 'info');
			},
			handleTextMessage(jsonString) {
				try {
					const message = JSON.parse(jsonString);
					console.log(`收到文本消息: ${message.type}`, 'debug');
					switch (message.type) {
						case 'hello':
							console.log(`服务器回应: Session ID ${message.session_id}`, 'success');
							break;
						case 'tts':
							if(message.state === 'sentence_start' && message.text) {
								this.addConversationMessage(message.text);
							}
							break;
						case 'llm':
							if(message.text && message.text !== '😊') {
								this.addConversationMessage(message.text);
							}
							break;
						default:
							console.log(`收到消息: ${jsonString}`, 'info');
					}
				} catch (e) {
					console.log(`解析JSON失败: ${e.message}`, 'error');
					console.log(`原始数据: ${jsonString}`, 'debug');
				}
			},
			handleBinaryMessage(arrayBuffer) {
				console.log(`收到二进制数据，大小: ${arrayBuffer.byteLength}字节`, 'debug');
			},
			
			toBack(){
				uni.navigateBack();
			},
			startNewDialog(){
				uni.showModal({
					title:'温馨提示',
					content:'是否开启新的一轮对话？',
					success: (res) => {
						if(res.confirm){
							clearInterval(timer)
							this.dialogList = [];
							this.question = '';
						}
					}
				})
			},
			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.sendTextMessage();
					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;
	}
	
	.page{
		background: #F6F6F8;
		padding: 0 30rpx 200rpx;
		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: #252525;
				line-height: 36rpx;
				margin-top: 36rpx;
				&.tip{
					font-family: PingFangSC, PingFang SC;
					font-weight: 400;
					font-size: 26rpx;
					color: #646464;
					line-height: 40rpx;
					margin-top: 20rpx;
				}
			}
		}
	
		.dialogs{
			width: 100%;
			padding-top: 34rpx;
			box-sizing: border-box;
			overflow-y: auto;
			padding-bottom: 50rpx;
			.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: #505050;
						line-height: 48rpx;
						margin-left: 20rpx;
					}
				}
				.da_content{
					padding: 30rpx 32rpx;
					margin-top: 20rpx;
					background: #FFFFFF;
					border-radius: 4rpx 24rpx 24rpx 24rpx;
					.dac_think{
						image{
							width: 40rpx;
							height: 40rpx;
						}
						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: #D9F159;
					border-radius: 24rpx 4rpx 24rpx 24rpx;
					font-family: PingFangSC, PingFang SC;
					font-weight: 400;
					font-size: 28rpx;
					color: #252525;
					line-height: 40rpx;
					// text-align: right;
					padding: 26rpx 30rpx;
				}
			}
		}
		.ask_box{
			width: 100%;
			min-height: 176rpx;
			background: #F6F6F8;
			padding: 0 30rpx 60rpx;
			position: fixed;
			left: 0;
			box-sizing: border-box;
			
			.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>