<template>
	<view class="uni-column">
		<view class="content" id="content" >
			<scroll-view id="scrollview" scroll-y="true" :scroll-with-animation="true"
			    :scroll-top="scrollTop">
				<view id="allmsgview">
					<message-show v-for="(message,index) in messages" :key="index" v-bind:message="message" :msgid="index" :chatType="chatType"
					@handleAd="handleAd" @reAsk="handleReAsk" @fullscreen="handleFullscreen" @handleResearch="handleResearch"></message-show>
				</view>
			</scroll-view>
		</view>
		<view class="foot">
			<view class="session-view">
				<!-- <view class="new" @click="handleCreateSession">
					换个话题
				</view> -->
				<button class="all" @click="handleShowAll">
					我的提问
				</button>
				|
				<button class="new" @click="handleDelAll">
					换个话题
				</button>
				|
				<button id="shareSessionBtn" open-type="share" class="shareSession"  @click="handleShareSession">
					分享
				</button>
			</view>
			<chat-input :disabled="chatStatus === 1 || leftTimes <= 0" :placeholder="placeholder" @send-message="getInputMessage" ></chat-input>
		</view> 
		<session-list ref="sessionlist" :allsessions="allsessions" :sessionOver="sessionOver"
			@loadMoreSession="loadMoreSession" 
			@handleDelAll="handleDelAll"
			@handleDelSesstion="handleDelSesstion"
			@changeSession="changeSession"
		></session-list>
	
		<uni-popup ref="fullscreen">
			<view class="fullscreen">
				<towxml :nodes="mdcontent"></towxml>
				<view class="btn-view ">
					<!-- <view class="btn">
						点赞
					</view> -->
					<view class="btn" @click="handleCopy">
						复制全文
					</view>
					<view class="btn" @click="handleCloseFullpage">
						关闭
					</view>
				</view>
			</view>
		</uni-popup>
	</view>
</template>

<script>
	import chatInput from '../components/chatinput.vue';
	import messageShow from '../components/messageshow.vue';
	import sessionList from '../components/sessionlist.vue'
	// import { Client } from '@stomp/stompjs
	import { WebSocket } from '@/common/websocket-uni.js';
	import { Stomp } from '@/common/stomp.js';	
	import webScoket from '@/common/socket.js'
	import { orderBy } from 'lodash'
	import { ask, getAnswer, shareSuccess, chatSessionList, createChatSession, delChatSession, chatHistory, adSuccess } from '@/api/index.js'
	import { dateFormat } from '@/common/util.js'
	import { chatDefaultMsg, chatOnlineMsg, msgOver, msgSensitive } from "@/common/config.js"
	import { CHAT_TYPE, CHAT_TYPE_NAME } from '@/common/enum.js';
	import {
		mapState,
		mapGetters,
		mapMutations
	} from 'vuex'
	let stompClient = ''
 
	var app = getApp();
	export default {
		data() {
			return {
				leftTimes: 5,
				timer: null,
				chatStatus: 0,
				allsessions: [],
				curSessionId: 0,
				page: 1,
				sessionOver: false,
				style: {
					pageHeight: 0,
					contentViewHeight: 0,
					footViewHeight: 90,
					mitemHeight: 0,
				},
				scrollTop: 0,
				messages: [this.chatType === CHAT_TYPE.ONLINE ? chatOnlineMsg : chatDefaultMsg],
				videoAd: null,
				mdcontent: '',
				fpcontent: '',
				counter: 0
			}
		},
		computed: {
			...mapState(['userId', 'userAvatar', 'settings', 'chatType']),
			...mapGetters(['getChatSeq']),
			placeholder() {
				if (this.leftTimes >= 5) {
					return '请输入提问内容'
				} else if (this.leftTimes > 0) {
					return `请输入提问内容, 还剩${this.leftTimes}次追问机会`
				} else {
					return `追问次数已用完，请新建话题`
				}
			}
		},	
		components: {
			chatInput,
			messageShow,
			sessionList
		},
		onLoad() {
			this.getSessionList()
			// this.subScribeMsg()
			// 在页面中定义激励视频广告
			const that = this
			// 在页面onLoad回调事件中创建激励视频广告实例
			if (wx.createRewardedVideoAd) {
				let videoAd = wx.createRewardedVideoAd({
					adUnitId: 'adunit-a1e7fbbe32c0a0d1'
				})
				this.videoAd = videoAd
				videoAd.onLoad(() => {})
				videoAd.onError((err) => {})
				videoAd.onClose((res) => {
					console.log('广告播放结束', res);
					if (res && res.isEnded) {
						// 正常播放结束，可以下发游戏奖励
						adSuccess().then((rst) => {
							if (rst.data && rst.data.timesByDay <= that.settings.ad.limitTimesByDay) {
								uni.showToast({
									title: `恭喜您，获得${that.settings.ad.addTimes}点算力`,
									icon: 'none',
									duration: 2000
								})
							}
						})
					} else {
						// 播放中途退出，不下发游戏奖励
					}
				})
			}
			console.log(CHAT_TYPE_NAME[`${this.chatType}`])
			uni.setNavigationBarTitle({
				title: `AI降临派 - ${CHAT_TYPE_NAME[this.chatType]}`
			})
		},
		onHide() {
			clearTimeout(this.timer)
		},
		onUnload() {
			clearTimeout(this.timer)
		},
		created: function () { 
			const res = app.globalData.systemInfo;
			console.log(app.globalData.systemInfo);
			this.style.pageHeight = res.windowHeight;
			this.style.contentViewHeight = res.windowHeight - res.screenWidth / 750 * (100); //像素
			// const listener = function (res) { console.log(res) }
			// uni.onKeyboardHeightChange(listener)
			// uni.offKeyboardHeightChange(listener) // 需传入与监听时同一个的函数对象
			
			wx.showShareMenu({
				withShareTicket: true,
				//设置下方的Menus菜单，才能够让发送给朋友与分享到朋友圈两个按钮可以点击
				menus: ["shareAppMessage", "shareTimeline"]
			})
		},

		methods: {
			dateFormat,
			parseMarkdown(content) {
				// this.fpcontent = content
				// let result = this.$towxml(content,
				// 	'markdown', {
				// 		// base: 'https://xxx.com', // 相对资源的base路径
				// 		theme: 'dark', // 主题，默认`light`
				// 		events: { // 为元素绑定的事件方法
				// 			tap: (e) => {
				// 				console.log('tap', e);
				// 			}
				// 		}
				// 	});
				// // 更新解析数据
				// this.mdcontent = result
				return content
			},
			handleReAsk() {
			},
			handleFullscreen(msg) {
				this.parseMarkdown(msg)
				this.$refs.fullscreen.open()
			},
			handleResearch(msg) {
				// 重新检索
			},
			handleCloseFullpage() {
				this.$refs.fullscreen.close()
			},
			handleCopy() {
				const that = this
				wx.setClipboardData({
					data: that.fpcontent, //这个是要复制的数据
					success (res) {
						wx.showToast({
							title: '复制成功',
							icon: 'success',
							duration: 1500
						})
					}
				})
			},
			handleAd() {
				// 用户触发广告后，显示激励视频广告
				this.videoAd.show().catch(() => {
				    // 失败重试
				    this.videoAd.load()
						.then(() => this.videoAd.show())
						.catch(err => {
							console.log('激励视频 广告显示失败')
						})
				})
			},
			getInputMessage: function (message) { //获取子组件的输入数据
				this.addQuestion(message.content);
				this.toAskQuestion(message.content);
			},
			addQuestion: function (question) { 
				this.messages.push({
					user: 'customer',
					content: question
				});
			},
			addMessage: function(msg, status = 'WAITING', replace = false) {
				const temp = {
					user: 'ai',
					content: msg,
					status
				}
				if (replace) {
					this.messages.splice(this.messages.length -1, 1, temp);
				} else {
					this.messages.push(temp);
				}
				this.startToScroll()
			},
			addAnswer: function(message, replace = false ) {
				const { id, question, answer, status, liked } = message
				const temp = {
					user: 'ai',
					content: answer,
					id, question, status, liked
				}
				if (replace) {
					this.messages.splice(this.messages.length -1, 1, temp);
				} else {
					this.messages.push(temp);
				}
				this.startToScroll()
			},
			startToScroll(time = 100) {
				setTimeout(() => {
					this.scrollToBottom();
				}, )
			},
			scrollToBottom: function () {
				var that = this;
				var query = uni.createSelectorQuery().in(this);;
			    query.select('#allmsgview').boundingClientRect();
				query.select('#scrollview').boundingClientRect();

				query.exec(function (res) {
					that.style.mitemHeight = 0;
					// res[0].forEach(function (rect) {
					// 	console.info('rect.height:',rect.height);
					// 	that.style.mitemHeight = that.style.mitemHeight + rect.height + 20;
					// });
					that.style.mitemHeight = res[0].height
					const scrollHeight = res[1].height
					if (that.style.mitemHeight > scrollHeight) {
						that.scrollTop = that.style.mitemHeight - scrollHeight;
					}
				});
			},
			getSessionList: async function() {
				wx.showLoading()
				const res = await chatSessionList(this.page, 20, this.chatType)
				wx.hideLoading()
				if (res.code === 0 && res.data) {
					this.sessionOver = res.data.list < 20
					this.allsessions = this.allsessions.concat(res.data.list)
					if (this.allsessions.length) {
						if (this.messages.length === 1 && this.page === 1) {
							this.curSessionId = res.data.list[0].id
							await this.getChatHistory()
						}
					} else {
						// 若为空，则新建一个话题
						await this.createNewSession(false);
					} 
				} 
			},
			loadMoreSession() {
				this.page++
				this.getSessionList()
			},
			changeSession(item) {
				this.curSessionId = item.id;
				this.getChatHistory()
				// this.$refs.popup.close()
				this.$refs.sessionlist.handleClose()
			},
			getChatHistory: async function(){
				const res = await chatHistory(this.curSessionId, 30)
				if (res.code === 0 && res.data) {
					const temps = [this.chatType === CHAT_TYPE.ONLINE ? chatOnlineMsg : chatDefaultMsg]
					const list = orderBy(res.data.list, ['id'])
					list.map(m => {
						const { id, question, answer, status, liked } = m
						const que = {
							user: 'customer',
							content: question
						}
						const ans = { ...m, content: answer ? answer : '请求异常',  user: 'ai' }
						
						temps.push(que)
						temps.push(ans)
					})
					
					if (this.chatType === CHAT_TYPE.ONLINE) {
						this.leftTimes = 5 - list.length
					}
					
					this.messages = temps
					this.startToScroll()
				}
			},
			toAskQuestion: async function (info) {
				
				const that = this;
				this.addMessage('AI正在思考，请稍候');
				const data = {
					question: info,
					sessionId: this.curSessionId
				}
				this.chatStatus = 1
				const res = await ask(data)
				console.log('res.data:', res.data)
				if(res.code === 0 && res.data) {
					// setTimeout(() => {
					// 	that.waitingAnswer(res.data.id)
					// }, 200)
					this.timer = setTimeout(() => {
						this.counter = 0
						this.chatType === CHAT_TYPE.ONLINE && this.leftTimes--
						this.getAnswer2(res.data.id)
					}, 500)
					// this.startSoctet()
					// this.subScribeMsg()
				} else if (res.code == 30003){
					// clearTimeout(this.timer)
					this.chatStatus = 0
					this.addMessage('您有其他提问正在进行中，请稍等。', 'FINISHED', true);
				} else if (res.code == 30004){
					// clearTimeout(this.timer)
					this.chatStatus = 0
					this.addMessage(msgOver, 'OVER', true);
				} else if (res.code == 30005){
					// clearTimeout(this.timer)
					this.chatStatus = 0
					this.addMessage(msgSensitive, 'FINISHED', true);
				} else if (res.code == 10001){
					// clearTimeout(this.timer)
					this.chatStatus = 0
					this.addMessage('会话超时, 请重新提问', 'FINISHED', true);
				} else {
					// clearTimeout(this.timer)
					this.chatStatus = 0
					this.addMessage('请求异常', 'DEFAULT', true);
				}
				
			},
			startSoctet() {
				const that = this
				Promise.all([webScoket.init('wss://api.aibaidu.com.cn/ws'), webScoket.client()]).then(result => {
				  stompClient = result[1]
				  stompClient.connect({}, () => {
					  stompClient.subscribe('/exchange/chat.mq/' + that.userId, response => {
						if (response.body) {
							const res = JSON.parse(response.body)
							console.log('收到订阅消息', res)
							if (res && res.id) {
								stompClient.disconnect()
								that.chatStatus = 0
								that.addAnswer(res, true);
							}
						}
					  })
					})
				})
			},
			subScribeMsg() {
				let socketTask = Stomp.client('wss://api.aibaidu.com.cn/ws');
				var that = this;
				socketTask.connect({}, function(frame) {
					console.log('socketTask 连接成功');
				    socketTask.subscribe('/exchange/chat.mq/' + that.userId, response => {
						var wsData = JSON.parse(response.body);
						console.log(wsData, 'wsData');
						if (wsData) {
							that.chatStatus = 0
							that.addAnswer(wsData, true);
							socketTask.disconnect()
						}
				    });
				});
			},
			startTyping(id) {
				this.timer = setTimeout(() => {
					this.getAnswer2(id)
				}, 500)
			},
			async getAnswer2(id) {
				if (this.counter > 200) {
					clearTimeout(that.timer)
					this.chatStatus = 0
					this.addMessage('会话超时, 请重新提问', 'DEFAULT', true);
					return
				}
				this.counter++
				const res = await getAnswer(id)
				if (res.code === 0 && res.data.status == 'FINISHED') {
					clearTimeout(this.timer)
					this.chatStatus = 0
					this.addAnswer(res.data, true);
				} else if (res.code === 0 && res.data.status == 'CANCELED') {
					clearTimeout(this.timer)
					this.chatStatus = 0
					this.addMessage('AI繁忙，稍后再试。', 'CANCELED', true);
				} else if (res.code === 0 && res.data.status == 'TYPING') {
					let answer = ''
					let replace = true
					const { onlineStatus } = res.data
					if (this.chatType === CHAT_TYPE.ONLINE && onlineStatus) {
					    const str = onlineStatus && onlineStatus.length > 50 ? onlineStatus.substring(0, 50): onlineStatus
						answer = res.data.answer ? res.data.answer : str + '...'
					} else {
						answer = res.data.answer + '...'
					}
					// this.chatStatus = 0
					this.addMessage(answer, 'DEFAULT', true);
					this.timer = setTimeout(() => {
						this.getAnswer2(id)
					}, 800)
				} else if (res.code === 0 && res.data.status == 'WAITING') {
					this.timer = setTimeout(() => {
						this.getAnswer2(id)
					}, 800)
				}
			},
			waitingAnswer: function(id) {
				this.chatStatus = 1
				const that = this
				let n = 0
				that.getAnswer(id)
				this.timer = setInterval(() => {
					if (n >= 10) {
						clearInterval(this.timer)
						that.waitingAnswer2(id)
						return
					}
					n++
					this.getAnswer(id, 1000)
				}, 1000)
			},
			waitingAnswer2: function(id) {
				const that = this
				let n = 0
				that.getAnswer(id)
				this.timer = setInterval(() => {
					if (n >= 15) {
						clearInterval(this.timer)
						this.chatStatus = 0
						this.addMessage('响应超时，请重新提问。', 'CANCELED', true);
					}
					n++
					this.getAnswer(id, 3000)
				}, 3000)
			},
			getAnswer: async function(id) {
				const that = this;
				const res = await getAnswer(id)
				if (res.code === 0 && res.data.status == 'FINISHED') {
					clearTimeout(that.timer)
					that.chatStatus = 0
					that.addAnswer(res.data, true);
				} else if (res.code === 0 && res.data.status == 'CANCELED') {
					clearTimeout(that.timer)
					that.chatStatus = 0
					that.addMessage('AI繁忙，稍后再试。', 'CANCELED', true);
				}
			},
			handleCreateSession() {
				if (this.chatStatus === 1) {
					wx.showToast({
						icon: 'none',
						title: '回答过程中, 请勿删除会话!',
						duration: 2000
					})
					return
				}
				
				this.createNewSession();
			},
			createNewSession: async function(showToash = true) {
				const res = await createChatSession(this.chatType)
				if (res.code === 0) {
					this.leftTimes = 5
					this.curSessionId = res.data.id
					this.allsessions.unshift(res.data)
					showToash && wx.showToast({
						icon: 'success',
						title: '好的,请提问!',
						duration: 1500
					})
				}
			},
			handleDelSesstion(item) {
				const that = this
				wx.showModal({
					title: '提示',
					content: '确定删除该会话吗？',
					success (res) {
					    if (res.confirm) {
					       that.deleteSession(item.id)
					    }
					}
				})
			},
			handleDelAll: function() {
				// this.$refs.popup.close()
				if (this.chatStatus === 1) {
					wx.showToast({
						icon: 'none',
						title: '回答过程中, 请勿新建会话!',
						duration: 2000
					})
					return
				}
				this.messages = [this.chatType === CHAT_TYPE.ONLINE ? chatOnlineMsg : chatDefaultMsg];
				this.createNewSession(true)
			},
			handleShowAll() {
				this.$refs.sessionlist.handleShowAll()
			},
			// 删除会话
			deleteSession: async function(id) {
				const res = await delChatSession(id)
				if (res.code === 0) {
					const index = this.allsessions.findIndex(m => m.id === id)
					this.allsessions.splice(index, 1)
					// 删除的是当前的会话，重新拉取会话历史
					if (this.curSessionId === id) {
						this.curSessionId = this.allsessions[0].id
						this.getChatHistory()
					}
				}
			},
			handleShareSession() {
				
			},
			onShareAppMessage: function (obj) {
				console.log('onShareAppMessage1', obj)
				// setTimeout(() => {
				// 	this.adShareTimes()
				// }, 2000)
				// let path = `/pages/ai/main/main?uid=${this.userId}`
				// let title = '加入AI降临派，与AI真神对话！'
				// if (obj.from === 'button' && obj.target.id === 'shareSessionBtn') {
				let	title = '我跟AI刚才这段对话非常有趣，你们也来看看'
				let	path = `/pages/ai/share/share?uid=${this.userId}&sid=${this.curSessionId}&ctype=${this.chatType}`;
				// }
				// 分享配置
				console.log('path', path);
				return { title,	path };
			},
			adShareTimes: async function() {
				const that = this
				const rst = await shareSuccess()
				if (rst.code === 0 && rst.data.now > rst.data.before) {
					wx.showToast({
						title: `恭喜您，获得${that.settings.share.addTimes}点算力`,
						icon: 'none',
						duration: 2000
					})
				}
			}
		}
	}
</script>

<style lang="less" scoped>
	
	.uni-column {
		height: 100%;
		background-color: @mainBg;
		display: flex;
		flex-direction: column;
	
		.content {
			height: 100%;
			display: flex;
			flex: 1;
			padding-bottom: 170rpx;
			box-sizing: border-box;
			#scrollview {
				height: 100%;
					
				#allmsgview {
					padding-bottom: 40rpx;
				}
			}
		}
		.foot {
			position: fixed;
			width: 100%;
			height: 170rpx;
			min-height: 170rpx;
			left: 0px;
			bottom: 0px;
			overflow: hidden;
			background-color: #33373f;
			padding: 4px 20rpx 20rpx;
			box-sizing: border-box;
			.session-view {
				height: 40rpx;
				padding: 0rpx 0rpx 16rpx;
				display: flex;
				justify-content: center;
				color: #efefef;
				button {
					border-radius: 4rpx;
					padding: 0 8rpx;
					background: none;
					color: #FFF;
					font-size: 14px;
					line-height: 1.5;
					border: none;
					text-align: right;
					display: block;
					display: flex;
					margin: inherit;
					&::after {
						content: none;
					}
					
					&:active {
						color: @mainColor;
					}
				}
				.new {
					padding-right: 24rpx;
					padding-left: 24rpx;
					// border-left: 1px solid;
				}
				.all {
					padding-right: 24rpx;
					padding-left: 24rpx;
				}
				.shareSession {
					padding-right: 24rpx;
					padding-left: 24rpx;
					// border-left: 1px solid;
				}
			}
		}
	
		
		.uni-popup .uni-popup__wrapper.center {
			width: 100%;
			.fullscreen {
				height: 100vh;
				width: 100%;
				padding: 0 0rpx 80rpx;
				background-color: @mainBg;
				overflow: auto;
				position: relative;
				box-sizing: border-box;
				.btn-view {
					position: fixed;
					bottom: 0;
					height: 80rpx;
					width: 100%;
					display: flex;
					justify-content: space-around;
					align-items: center;
					background-color: darken(@mainBg, 5%);
					.btn {
						color: #ededed;
						width: 180rpx;
						line-height: 60rpx;
						&:active {
							color: @mainColor;
						}
					}
				}
				
			}
		}
	}
</style>
