<template>
	<mobile-frame>
		<view class="main">
			<view class="one">
				<!-- 聊天内容 -->
				<scroll-view class="scroll-view" scroll-y="true" scroll-with-animation="true"
					:scroll-into-view="scrollToView" refresher-enabled="true" :refresher-triggered="triggered"
					@refresherrefresh="getFresh">
					<view class="list-scroll-view">
						<view class="chat-ls" v-for="(item,index) in msgList" :key="index" :id="'msg'+ index">
							<view class="chat-time" v-if="item.time != ''">
								{{item.time}}
							</view>
							<view class="msg-m msg-left" v-if="item.speaker !=  user._id">
								<image @tap="toShop()" class="user-img"
									:src="shop.logo&&shop.logo.length>0?shop.logo[0].url:''">
								</image>
								<!-- 文字 -->
								<view class="message" v-if="item.msg_type =='0'">                           
									<view class="msg-text">{{item.content}}</view>
								</view>
								<!-- 图像 -->
								<view class="message img" v-else-if="item.msg_type =='1'"
									@tap="previewImg(item.content)">
									<image :src="item.content" class="msg-img" mode="widthFix"></image>
								</view>
							</view>
							<view class="msg-m msg-right" v-else-if="item.speaker == user._id">
								<image class="user-img" :src="user.icon&&user.icon.length>0?user.icon[0].url:''">
								</image>
								<!-- 文字 -->
								<view class="message" v-if="item.msg_type =='0'">
									<view class="msg-text">{{item.content}}</view>
								</view>
								<!-- 图像 -->
								<view class="message img" v-else-if="item.msg_type =='1'"
									@tap="previewImg(item.content)">
									<image :src="item.content" class="msg-img" mode="widthFix"></image>
								</view>
							</view>
						</view>
					</view>
				</scroll-view>
			</view>
			<view class="two">
				<submit_1 @inputs="inputs" @heights="heights"></submit_1>
			</view>
		</view>
	</mobile-frame>
</template>

<script>
	import moment from 'moment';
	import submit_1 from './components/submit_1.vue';
	export default {
		components: {
			submit_1,
		},
		data() {
			return {
				// 用户信息
				user: {},
				// 房间号id
				id: '',
				// 店铺信息
				shop: {},
				shop_id: "",
				// 历史记录
				msgList: [],
				total: 0,
				skip: 0,
				limit: 10,
				page: 0,
				// 判断是否跳到最后一条
				is_bottom: true,
				// 判断是否下拉刷新复位
				triggered: false,
				scrollToView: '', //滑动最后一条信息
				isSocketOpen: false, //socket是否打开
				pingpangTimes: null, //socket心跳计时器
				timeoutnum: null, //断开 重连倒计时，
				closeType: 1, //断开判断：0代表不重连，1代表重连
			};
		},
		onShow() {
			const that = this;
			// that.initWebpack(); //初始化
			that.closeType = 1 //进入改为1，代表如果断开链接自动重连
			that.clearPage();
			if (that.id) that.search()
		},
		onLoad: async function(e) {
			const that = this;
			that.$set(that, `id`, e.id);
			that.$set(that, `shop_id`, e.shop);
			that.watchlogin();
		},
		beforeDestroy() {
			const that = this;
			that.closeType = 0 //离开页面前改为0，代表离开后断开链接不再重连
			clearInterval(that.pingpangTimes) //清除socket心跳定时器
			uni.closeSocket() //关闭socket
		},
		methods: {
			// 监听用户是否登录
			watchlogin() {
				const that = this;
				uni.getStorage({
					key: 'token',
					success: function(res) {
						let user = that.$jwt(res.data);
						if (user) that.$set(that, `user`, user)
					}
				})
			},
			// 查询历史记录
			async search() {
				const that = this;
				let info = {
					skip: that.skip,
					limit: that.limit,
					room: that.id
				}
				let res;
				res = await that.$api(`/chatRecord`, `GET`, {
					...info,
				}, 'chat');
				if (res.errcode == '0') {
					let msgList = [...res.data, ...that.msgList];
					msgList.sort(function(a, b) {
						return a.time > b.time ? 1 : -1;
					});
					that.$set(that, `msgList`, msgList);
					that.$set(that, `total`, res.total)

				} else {
					uni.showToast({
						title: res.errmsg,
						icon: 'none'
					})
				}
				// 查询房间信息
				// 如果是下拉刷新聊天记录不请求房间信息
				if (that.is_bottom == true) {
					res = await that.$api(`/room/${that.id}`, `GET`, {}, 'chat')
					if (res.errcode == '0') {
						that.$set(that, `shop`, res.data && res.data.shop);
						if (res.data && res.data.shop && res.data.shop.name) {
							uni.setNavigationBarTitle({
								title: res.data.shop.name
							});
						}
					} else {
						uni.showToast({
							title: res.errmsg,
							icon: 'none'
						})
					}
				}
				let id = that.msgList.filter(i => {
					if (i.speaker != that.user._id) return i.is_read = '0';
				})
				let ids = id.map(i => {
					return i._id
				})
				if (ids.length > 0) {
					// 信息已读
					res = await that.$api(`/chatRecord/read`, `POST`, {
						ids
					}, 'chat')
					if (res.errcode == '0') {} else {
						uni.showToast({
							title: res.errmsg,
							icon: 'none'
						})
					}
				}
				// 跳转到最后一条数据 与前面的:id进行对照
				// 如果是下拉刷新聊天记录不跳到最后一条
				if (that.is_bottom == true) that.goBottom();
			},
			// 初始化websocket链接
			initWebpack() {
				const that = this;
				let config = that.$config;
				let url = `wss://${config.stompUrl}/ws/exchange/t_m_dev_local/635f82e62df39d4755a25a4a`;
				//创建新的socket连接前确保旧的已关闭
				uni.closeSocket();
				//创建一个socket连接
				uni.connectSocket({
					url,
					success: function(res) {
						console.log(res, 's');
					},
					fail: function(err) {
						console.log(err, 'e');
					}
				});
				//监听socket打开
				uni.onSocketOpen(() => {
					that.isSocketOpen = true
					console.log('WebSocket连接已打开！');
				})
				//监听socket关闭
				uni.onSocketClose(() => {
					that.isSocketOpen = false
					//断开链接时判断
					if (that.closeType == 0) return
					that.reconnect(); //重连
					console.log('WebSocket连接已关闭！');
				})
				//监听socket错误
				uni.onSocketError(() => {
					that.isSocketOpen = false
					//断开链接时判断
					if (that.closeType == 0) return
					that.reconnect(); //重连
					console.log('WebSocket连接打开失败');
				})
				//监听socket消息
				uni.onSocketMessage((res) => {
					let info = JSON.parse(res.data)
					if (info.cadmin != 5) {
						that.msgList = that.msgList.concat(info) //获取实时聊天内容信息
					}
				})
				//先确保清除了之前的心跳定时器
				clearInterval(that.pingpangTimes)
				//每过一段时间发送一次心跳，发送Ping,服务器会反馈pong，这样操作以保持socket一直是连接状态，防止断开连接，心跳停止
				that.pingpangTimes = setInterval(() => {
					uni.sendSocketMessage({
						data: "ping",
						success: () => {},
						fail: () => {
							that.isSocketOpen = false
						}
					});
				}, 60000)
			},
			//重新连接
			reconnect() {
				const that = this;
				//防止重复链接
				if (that.isSocketOpen) return;
				that.isSocketOpen = true;
				//没连接上会一直重连，设置延迟避免请求过多
				that.timeoutnum && clearTimeout(that.timeoutnum);
				that.timeoutnum = setTimeout(function() {
					that.initWebpack(); //新连接
				}, 5000);
			},
			// 进行图片的预览
			previewImg(e) {
				const that = this;
				// 预览图片
				uni.previewImage({
					current: 0,
					urls: [e],
					longPressActions: {
						itemList: ['发送给朋友', '保存图片', '收藏'],
						success: function(data) {
							console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片');
						},
						fail: function(err) {
							console.log(err.errMsg);
						}
					}
				});
			},
			//接受输入内容
			async inputs(e) {
				const that = this;
				let user = that.user
				if (user._id) {
					//时间间隔处理
					let data = {
						"room": that.id,
						"speaker": user._id,
						"content": e.message,
						"time": moment().format('YYYY-MM-DD HH:mm:ss'),
						"msg_type": e.type
					};
					// 发送给服务器消息
					// if (that.isSocketOpen) { //socket连接正常
					if (!that.id) data.shop = that.shop_id
					let res = await that.$api(`/chatRecord`, `POST`, data, 'chat');
					if (res.errcode == '0') {
						that.msgList.push(res.data);
						// data = JSON.stringify(data) //后端规定的评论数据格式:json转字符串
						// uni.sendSocketMessage({
						// 	data,
						// 	success: () => {
						// 		uni.showToast({
						// 			title: '发送成功',
						// 			icon: 'none'
						// 		})
						// 	},
						// 	fail: () => {
						// 		uni.showToast({
						// 			title: '发送失败，请稍后再试或重新进入此页面尝试',
						// 			icon: 'none'
						// 		})
						// 	}
						// });
					} else {
						uni.showToast({
							title: res.errmsg,
							icon: 'none'
						})
					}
					// } else { //socket已断开
					// 	uni.showToast({
					// 		title: '聊天断开啦，请重新进入此页面尝试 ~',
					// 		icon: 'none'
					// 	})
					// }
					// 跳转到最后一条数据 与前面的:id进行对照
					that.goBottom();
				} else {
					uni.showToast({
						title: '未登录账号无法发送消息 ，请及时登录！',
						icon: 'none'
					})
				}
			},
			// 店铺
			toShop() {
				uni.navigateTo({
					url: `/pagesHome/shop/index`
				})
			},
			//输入框高度
			heights(e) {
				const that = this;
				that.goBottom();
			},
			// 滚动到底部
			goBottom() {
				const that = this;
				that.scrollToView = '';
				that.$nextTick(function() {
					that.scrollToView = 'msg' + (that.msgList.length - 1)
				})
			},
			// 下拉刷新分页
			getFresh(e) {
				const that = this;
				that.triggered = true;
				let list = that.msgList;
				let limit = that.limit;
				setTimeout(() => {
					if (that.total > list.length) {
						uni.showLoading({
							title: '加载中',
							mask: true
						})
						let page = that.page + 1;
						that.$set(that, `page`, page)
						let skip = page * limit;
						that.$set(that, `skip`, skip)
						that.$set(that, `is_bottom`, false)
						that.search();
						uni.hideLoading();
					} else {
						uni.showToast({
							title: `没有更多聊天记录了`,
							icon: 'none'
						})
					}
					that.triggered = false;
				}, 1000)
			},
			clearPage() {
				const that = this;
				that.$set(that, `msgList`, [])
				that.$set(that, `skip`, 0)
				that.$set(that, `limit`, 10)
				that.$set(that, `page`, 0)
			},
		}
	}
</script>

<style lang="scss">
	.main {
		display: flex;
		flex-direction: column;
		width: 100vw;
		height: 100vh;
		overflow: hidden;

		.one {
			position: relative;
			flex-grow: 1;

			.scroll-view {

				.chat-ls {
					padding: 2vw 2vw 0 2vw;

					.chat-time {
						font-size: 24rpx;
						color: rgba(39, 40, 50, 0.3);
						line-height: 34rpx;
						padding: 10rpx 0rpx;
						text-align: center;
					}

					.msg-m {
						display: flex;
						padding: 20rpx 0;

						.user-img {
							flex: none;
							width: 80rpx;
							height: 80rpx;
							border-radius: 40rpx;
							border: 1px solid #c0c0c0;
						}

						.message {
							flex: none;
							max-width: 480rpx;
						}

						.img {
							margin: 0 20rpx 0 0;
						}

						.msg-text {
							font-size: 32rpx;
							color: rgba(39, 40, 50, 1);
							line-height: 44rpx;
							padding: 18rpx 24rpx;
							word-break: break-all;
						}

						.msg-img {
							max-width: 400rpx;
							border-radius: 20rpx;
						}
					}

					.msg-left {
						flex-direction: row;

						.msg-text {
							word-break: break-all;
							margin-left: 16rpx;
							background-color: #f1f1f1;
							border-radius: 0rpx 20rpx 20rpx 20rpx;
						}

						.ms-img {
							margin-left: 16rpx;
						}

					}

					.msg-right {
						flex-direction: row-reverse;

						.msg-text {
							margin-right: 16rpx;
							background-color: rgba(255, 228, 49, 0.8);
							border-radius: 20rpx 0rpx 20rpx 20rpx;
						}

						.ms-img {
							margin-right: 16rpx;
						}
					}
				}
			}
		}

		.two {
			background-color: #f0f0f0;
			border-top: 1px solid rgba(39, 40, 50, 0.1);
		}
	}

	.scroll-view {
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;

		.list-scroll-view {
			display: flex;
			flex-direction: column;
		}
	}
</style>
