<template>
	<view class="content">
		<!-- <view class="v-html-click" @tap="handleClick()" ref="htmlContent" v-html="code"></view>
		<span v-copy="123">复制</span> -->
		<scroll-view scroll-y="true" :scroll-top="scroll_top" style="top: 0%;width: 100vw;height:90vh;">
			<view class="scroll-view-text">
				<view  style=" margin-right: 5%; margin-left: 5%; margin-top: 3%; display: flex;user-select: text;" v-for="(msgIndex,index) in recvMsgQueue ">
					<!-- ai 的消息结构体 -->
					<view v-if="isAItell(recvMsgQueue[index].who_msg)"  style="display: flex; width: 100%;height: 100%;margin-bottom: 3%;">
						<image  :src="make_avatar(recvMsgQueue[index].who_msg)" style="width: 150upx;height: 150upx;margin-right: 1%;"></image>
						<view  style="margin-bottom: 3%; margin-top: 1%;margin-left: 1%;padding: 1%; width: 70vw;background: #EFEFEF;border-radius: 10rpx 10rpx 10rpx 10rpx;">
							<!-- <text  style="width: 100%;align-self: auto;">
								{{recvMsgQueue[index].msg_text}}
							</text> -->
							<view @tap="handleClick()" style="width: 100%;" class="htmlContent" ref="htmlContent" v-html="returnText(recvMsgQueue[index].msg_text)"></view>
							<view @click="stopRecv()" v-if="recvStatus&&recvMsgQueue[index].isFinish==false" style="display: flex;width: 100%;align-items: center;justify-content: center;">
								<image src="../../static/closed.png" style="width: 50upx;height: 50upx;align-self: center;"></image>
							</view>
							
						</view>
					</view>
				
					<!-- 我发送 的消息结构体 -->
					<view v-if="!isAItell(recvMsgQueue[index].who_msg)"  style="display: flex; width: 100%;height: 100%;margin-bottom: 3%;">
						
						<view style="justify-content: end;display: flex; width: 100%;height: 100%; ">
							<view style="justify-content: space-between; display: flex;;align-items:center; padding: 1%;margin-right: 2%;background:green;border-radius: 10rpx 10rpx 10rpx 10rpx;">
								<view></view>
								<text  style="align-self: auto;color: aliceblue;">
									{{recvMsgQueue[index].msg_text}}
								</text> 
							</view>
							<view>
								<image  :src="make_avatar(recvMsgQueue[index].who_msg)" style="width: 150upx;height: 150upx;right: 0%;"></image>
							</view>
							
						</view>
						
					</view>
					
				</view>
			</view>
		</scroll-view>
		
		<view style="display: flex;width: 100vw;height: 10vh;bottom: 0%;">
	<!-- 		<view style="background-color: gainsboro;width: 90%;">
				<input :disabled="disabled"  placeholder-style="margin-left: 5%;" style="width: 100%;height: 10vh;" @input="onKeyInput" :value="inputValue" placeholder="请输入消息内容(使用 Enter 发送)"/>
			</view> -->
			<view style="background-color: gainsboro;width: 90%;" class="textarea-box">
				<textarea  v-model="inputValue" :cursor-spacing="15" class="textarea" auto-height="true"
					@keyup.shift="onKeyup('shift')" @keydown.shift="onKeydown('shift')"
					@keydown.enter="onKeydown('enter')" :disabled="disabled"
					placeholder="请输入消息内容(使用 Enter 发送)" :maxlength="-1" 
					placeholder-class="input-placeholder"></textarea>
			</view>
			<view style="width: 10%;position: relative;">
				<view v-if="recvStatus==false" style="width: 100%; height: 100%; display: flex;  background-color:slategray;color: aliceblue;align-items: center;justify-content: center" @click="sendMsg">
					发送
				</view>
				<view :animation="ani" :style="ani_style">
					<image v-if="recvStatus==true"  src="../../static/apple.png" style="width: 100%;height: 100%;"></image>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	import marked from '../marked/marked.min.js';
	import config from './config.js';
	import hljs from "../highlight.js/lib/common.js";
	import "highlight.js/styles/atom-one-dark.css";
	import  './v-copy.js';
	// 键盘的shift键是否被按下
	let shiftKeyPressed = false
	export default {
		
		components:{
			marked
		},
		
		mounted(){			
				marked.setOptions({
				          renderer: new marked.Renderer(),
				          gfm: true,
				          tables: true,
				          breaks: false,
				          pedantic: false,
				          sanitize: false,
				          smartLists: true,
				          smartypants: false,
						  highlight: function (code) {
						  					return hljs.highlightAuto(code).value;
						 },
						 langPrefix:"hljs language-"
				});
				
			
		},
		data() {
			return {
				code:'',
				title: 'Hello',
				disabled: false,
				socketOpen:false,
				socketMsgQueue:[],
				recvMsgQueue:[],
				sendMsgQueue:[],
				inputValue: '',
				_socketTask:null,
				scroll_text_:"\n",
				sendStatus:false,
				recvStatus:false,
				all_src_list:[],
				src_index:0,
				scroll_top:0,
				ani:'',
				ani_style:{
					width: "100upx",height: "100upx",rotate: 0,left:"25%",right:"25%",position:"absolute"
				},
				angle:359,
			}	
		},
		onLoad() {
			this.initTcp();
		},
		methods: {
			// #ifdef H5 && VUE2
			onKeydown(keyname) {
				if (keyname == 'shift') {
					//按下了shift键
					shiftKeyPressed = true;
				}
				let self = this;
				// 按下了回车 且 之前没按下 shift
				if (keyname == 'enter' && !shiftKeyPressed) {
					this.$nextTick(() => {
						// self.sendMsg();
					})
				}
			},
			onKeyup(keyname) {
				if (keyname == 'shift') {
					//按下了shift键
					shiftKeyPressed = false;
				}
			},
			// #endif
			setCopy(content){
			    // 使用#ifdef H5和#endif控制各端调用情况
			
			    // 该方法不支持h5
			    //#ifndef H5
			    uni.setClipboardData({
			        data: String(content), // 必须字符串
			        success: function () {
			            console.log('success');
			        }
			    });
			    //#endif
			
			    // h5端赋值方法，使用创建节点
			    // #ifdef H5
			    if (!document.queryCommandSupported('copy')) { // 兼容某些浏览器的判断
			        console.log('该浏览器不支持')
			    }
			    let textarea = document.createElement("textarea")
			    textarea.value = content
			    textarea.readOnly = "readOnly"
			    document.body.appendChild(textarea)
			    textarea.select() // 选择对象
			    textarea.setSelectionRange(0, content.length) // 核心
			    let result = document.execCommand("copy") // 执行浏览器复制命令
			    if (result) {
			        uni.showToast({
			            title: '复制成功',
			            duration: 2000
			        });
			    }
			    textarea.remove()
			    // #endif
			},
			updateSrcList(){
				let self = this;
				let list = this.getIndexList(self.scroll_text_);
				for (var i = 0; i < list.length; i+=2) {
					let start = list[i];
					let end = list[i+1];
					self.all_src_list.push(self.scroll_text_.substring(start,end))
				}	
				console.log("updateSrcList",self.all_src_list,self.scroll_text_)
			},
			stopRecv(){
				let self =this;
				self._socketTask.close()
				self.initTcp(true);
				self.finish_recv();
			},
			 handleClick(e) {
				e = e || window.event;
				let target = e.target || e.srcElement;
				let name = target.tagName.toLowerCase();
				let self =this;
				if(name.substring(0,3)=="abc"){
					let name_list = name.split('_');
					if(name_list.length>0){
						let index = parseInt(name_list[1])-1;
						console.log("handleClick",index,self.all_src_list)
						self.setCopy(self.all_src_list[index])
					}
					console.log("handleClick",self.all_src_list[index])
					console.log(target.tagName.toLowerCase())
				}
				console.log(name.substring(0,3))
			  },
			copyUpdates(){
				let self = this;
				let str = self.recvMsgQueue[self.recvMsgQueue.length-1].msg_text
				let key = "</code></pre>";
				let index = self.all_src_list.length;
				while(str.indexOf(key) != -1){
					index++;
					let s_tag =   "</code><abc_"+index+" class=\"copy-button\">Copy</abc_"+index+"></pre>"
					console.log("s_tag",s_tag)
					str=str.replace("</code></pre>", s_tag)
				}
				// str=str.replaceAll("</code></pre>", "</code><abc class=\"copy-button\">Copy</abc></pre>")
				self.recvMsgQueue[self.recvMsgQueue.length-1].msg_text = str
				// console.log("copyUpdates",str)
				self.$forceUpdate();
			},	
			
			getIndexList(box_str){
				let box = box_str;
				let boxarr=[];
				let pos = box.indexOf('```');
				while(pos>-1){
					boxarr.push(pos);
					pos= box.indexOf('```',pos+1);
				}
				return boxarr

			},
			returnText(text){
				return "<style> pre {position: relative;}.copy-button { position: absolute; top: 0;right: 0;padding: 4px 8px;background-color: #333;color: #fff;cursor: pointer;user-select: none;} p {line-height: 2;} li{line-height: 1.5;} table {border-collapse: collapse;width: 100%;font-family: Arial, sans-serif;font-size: 14px;}table th,table td {border: 1px solid #ddd;padding: 8px;text-align: left;}</style>"+text
			},
			// 滚动窗口以显示最新的一条消息
			showLastMsg() {
				let self = this;
				let container = uni.createSelectorQuery().in(this).select(".scroll-view-text");
				// 利用uniapp提供的接口获取可视区域的高度和滚动高度
					// let query=uni.createSelectorQuery()
					// let container=query.select('.box');
					container.fields({
						// rect:true,   //是否返回节点布局位置信息{left,top,right,bottom}
						size:true,  //是否返回节点尺寸信息{width，height}
						scrollOffset:true //是否返回节点滚动信息{scrollLeft,scrollTop}
					},(res)=>{
						self.scroll_top = res.height;
						// console.log(res)
				}).exec()
			},
			isAItell(type){
				if(type===config.type_ai){
					return true;
				}
				return false;
			},
			make_avatar(type){
				if(type===config.type_ai){
					return "../../static/PubImgs_avatar_avatar7.png";
				}
				return "../../static/PubImgs_avatar_avatar8.png";
			},
			isShow(text){
				return text!="";
			},
			initAni(){
				let self = this;
				let action = uni.createAnimation({
						  duration: 10000,
						  transformOrigin:"50% 50% 0",
						  timingFunction: "ease",
						  delay: 0
						})
				self.angle+=360;
				action.rotate(self.angle).step()
				self.ani =  action.export()
				setTimeout(self.initAni,10000)
			},
			tryReConnect(){
				let self = this;
				uni.showLoading({
					title:"正在尝试重新连接"
				})	
				self.disabled = false;
				self.socketOpen = false;
				self.initTcp()
			},
			initTcp(isStopRecv=false){
				let self = this;		
				self._socketTask = new WebSocket("ws://47.88.86.123:8000/ws") ;
				self._socketTask.onopen = function (res) {
				  console.log('WebSocket连接已打开！');
				  if(!isStopRecv){
					  uni.showLoading({
					  						title:"登录成功"
					  })
				  }
				  self.socketMsgQueue = [];
				  uni.hideLoading()
				  self.socketOpen = true;
					  
				};
				self._socketTask.onclose = (res)=>{
					// uni.showModal({
					// 	showCancel:false,
					// 	title:"WebSocket is onclose "
					// })
					console.log("WebSocket is onclose")
					self._socketTask.close()
					self.tryReConnect()
				};
				self._socketTask.onerror= function (res) {
					// uni.showModal({
					// 	showCancel:false,
					// 	title:"WebSocket连接打开失败，请检查"
					// })
				  console.log('WebSocket连接打开失败，请检查！');
				};
				
				self._socketTask.onmessage = function (res) {
				  // console.log('收到服务器内容：' + res.data);
				  let content = ''
				  let data = JSON.parse(res.data);
				  content = data.content+''
				  if(self.sendStatus){
					  self.sendStatus = false;
					  // content = '▪ ';
					  self.scroll_text_ = '';
					  // let index = self.recvMsgQueue.length>0?self.recvMsgQueue.length:0
					  self.recvMsgQueue.push({who_msg:config.type_ai,msg_type:0,msg_text:'',isFinish:false})
					  self.startUpdateView()
				  }
					// 在dom渲染完毕后 使聊天窗口滚动到最后一条消息
					self.$nextTick(() => {
						self.showLastMsg()
					})
				  // console.log('收到服务器内容：' +content );
				  let finish_reason = data.finish_reason+''
				  if(content!='null'){
					  self.scroll_text_+=content;
					  // if(content=='.'||content=='。'){
						 //  self.scroll_text_+='\n▪ ';
					  // }
				  }
				  if(finish_reason!='null'){
					  self.finish_recv()
					  // self.recvStatus = false;
					  // self.disabled = false;
					  // clearTimeout(self.initAni)
					  // self.scroll_text_+="\n"
					  // console.log("self.recvMsgQueue",self.scroll_text_)
					  // self.stopUpdateView();
					  // self.copyUpdates();
					  // self.updateSrcList();
					  // self.recvMsgQueue[self.recvMsgQueue.length-1].isFinish = true;
				
				  }else{
					self.recvMsgQueue[self.recvMsgQueue.length-1].msg_text = marked.parse(self.scroll_text_);
				  }
				  // console.log("self.recvMsgQueue.length",self.recvMsgQueue.length)
				};
			},
			async finish_recv(){
				let self = this;
				self.recvStatus = false;
				self.disabled = false;
				clearTimeout(self.initAni)
				self.scroll_text_+="\n"
				console.log("self.recvMsgQueue",self.scroll_text_)
				self.stopUpdateView();
				self.copyUpdates();
				self.updateSrcList();
				self.recvMsgQueue[self.recvMsgQueue.length-1].isFinish = true;
			},
			async sendMsg(){
				// 如果内容为空
				if (!this.inputValue) {
					// 弹出提示框
					return uni.showToast({
						// 提示内容
						title: '内容不能为空',
						// 不显示图标
						icon: 'none'
					});
				}
				this.sendSocketMessage(this.inputValue)
			},
			onKeyInput(event) {
				this.inputValue = event.target.value
			},
			startUpdateView(){
				let self = this;
				self.$forceUpdate();
				setTimeout(self.startUpdateView,500)
			},
			stopUpdateView(){
				let self = this;
				clearTimeout(self.startUpdateView)
			},
			sendSocketMessage(msg) {
				let self = this;
			  if (this.socketOpen) {
				 //  uni.showLoading({
					// title:"正在发送"
				 //  })
				self.sendStatus = true;
				self.disabled = true;
				self.ani_style.rotate = 0;
				self.inputValue = '';
				self.initAni();
				self.recvMsgQueue.push({who_msg:config.type_self,msg_type:0,msg_text:msg,isFinish:false})
				self.recvStatus = true;
				self._socketTask.send(msg)
			  } else {
			    this.socketMsgQueue.push(msg);
			  }
			},
		

		}
	}
</script>

<style>
	.content {
		height: 100vh;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		/* position: relative; */
	}
	.text-area {
		display: flex;
		justify-content: center;
	}

	.title {
		font-size: 36rpx;
		color: #8f8f94;
	}
	
	.textarea-box,
	.textarea {
		width: 100%;
		height: 100%;
	},
	textarea-box {
		width: 100% !important;
	}
	
	.textarea-box,
	.textarea,
	textarea,
	textarea-box {
		/* height: 120px; */
	}

	.textarea-box {
		background-color: #FFF;
	}
</style>

