<script setup>
	/**
	 * 聊天页面
	 */
	// 腾讯云聊天
	import TencentCloudChat from '@tencentcloud/chat';
	import {
		ref,
		reactive,
		nextTick,
		onUnmounted,
		onMounted,
		computed,
		getCurrentInstance,
		watch,
	} from 'vue'
	// api
	import api from '@/api/index.js'
	// 工具库
	import util from '@/common/js/util.js'
	import {
		onLoad,
		onReady,
		onPageScroll,
		onUnload
	} from "@dcloudio/uni-app"
	import {
		getHistoryMsg
	} from './fn.js'

	// 单条消息
	import newsTemplate from './components/news-temp'
	// 表情
	import emoji from './emoji.vue'
	// 语音条
	import JyVoice from './jy-voice.vue'
	// 加号菜单
	import JyPlus from './jy-plus.vue'
	// 顶部
	import apex from '@/components/header/apex.vue'

	import {
		useStore
	} from 'vuex'
	const {
		proxy
	} = getCurrentInstance()
	const store = useStore()

	// 聊天对象
	const msg = reactive({
		// 聊天对象
		id: '',
		// 聊天类型 C2C单聊 GROUP群聊
		type: '',
		// 群人数 
		num: '',
		// 是否客服聊天
		isCustomer: false,
	})
	// 输入的内容
	const content = ref('')
	// 加载
	const loading = ref(false)
	// 用户信息
	const userinfo = computed(() => {
		let result = store.state.userinfo
		return result
	})
	// 列表数据
	const list = reactive({
		// 消息列表
		messageList: [],
		// 用于续拉,分页续拉时需传入该字段
		nextReqMessageID: undefined,
		// 表示是否已经拉完所有消息
		isCompleted: false,
	})
	// 页面标题
	const pageTitle = ref('')
	// 滚动条位置
	const top = ref(0)
	// 工具条的高度
	const toolHeight = ref(0)
	// 当前操作的元素
	const messageItem = ref({})
	// 工具栏状态 voice录音 input输入框 emoji表情 plus加号菜单
	const toolStatus = ref('input')
	// video路径
	const videoUrl = ref('')
	// 视频上下文
	const videoContext = ref(null)
	// 红包对象
	const redPacket = reactive({})
	// 输入框聚焦
	const inputFocus = ref(false)

	onLoad(option => {
		// 标题
		let title = ''
		// 标题
		if (option.name) title = option.name
		// 聊天对象id
		if (option.msgId) msg.id = option.msgId
		// 聊天类型
		if (option.type) {
			msg.type = option.type
			// 如果是群组
			if (option.type == 'GROUP') {
				msg.num = option.num
				title = `(${option.num})${option.name}`
			}
		}
		// 标题
		if (title) pageTitle.value = title
		// 是否客服
		if (option.isCustomer) msg.isCustomer = option.isCustomer

		// 开启消息监听
		addListener()
		// 获取历史消息
		getHistory({
			callback: scrollToBottom
		})
		// #ifdef APP
		uni.onKeyboardHeightChange((rs) => {
			ghostBox.value.height = rs.height + 'px'
			nextTick(() => {
				scrollToBottom()
			})
		})
		// #endif
	})

	onReady(() => {
		uni.createSelectorQuery().in(proxy).select('#tool').boundingClientRect((rect) => {
			toolHeight.value = rect.height
		}).exec();
		// 
		videoContext.value = uni.createVideoContext('video')
	})

	onPageScroll((ev) => {
		onContentScroll(ev)
	})

	onUnload(() => {
		// #ifdef APP
		uni.offKeyboardHeightChange(() => {})
		// #endif
		videoContext.value.stop()
	})

	// 开启监听消息
	function addListener() {
		let onMessageReceived = function(event) {
			console.log('TencentCloudChat.EVENT.MESSAGE_RECEIVED', event)
			setTimeout(() => {
				// 获取历史记录
				getHistory({
					msgId: '',
					limit: 1,
				})
			}, 200)
		}

		uni.$chat.on(TencentCloudChat.EVENT.MESSAGE_RECEIVED, onMessageReceived);
	}

	// 监听内容滚动
	function onContentScroll(ev) {
		if (ev.scrollTop == 50) getMoreHistroy()
		debounce(() => {
			top.value = ev.detail.scrollTop
		})
	}

	// 点击发送
	function handleSend() {
		inputFocus.value = false

		// 发送消息
		sendMsg({
			query: {
				formId: userinfo.value.id,
				toUserId: msg.id,
				msgType: TencentCloudChat.TYPES.MSG_TEXT,
			},
			data: {
				text: content.value
			},
			success: () => {
				// 清空已发送的消息
				content.value = ''
				inputFocus.value = true
			}
		})
	}

	/**
	 * 加号菜单发送
	 * @param {Object} message 消息对象
	 */
	function handlePlusSend(message) {
		sendMsg(message)
	}

	/**
	 * 发送消息
	 * @param {Object} param
	 */
	function sendMsg(param) {
		// 
		let request = api.news.sendUserMsg
		// 
		if (msg.type == 'GROUP') request = api.news.sendGroupMsg
		// if (msg.isCustomer) request = api.news.sendCusomterService 

		// 发送消息
		request({
			query: param.query,
			data: param.data,
		}).then((rs) => {
			if (rs.code == 200) {
				// getHistory({
				// 	msgId: '',
				// 	limit: 1,
				// })
				param.success ? param.success() : ''
				return
			}
			util.alert({
				content: rs.msg,
				showCancel: false,
			})
		}).catch((rs) => {
			console.log('sendMsg error:', rs);
		})
	}

	/**
	 * 打开红包详情
	 * @param {Object} ev
	 */
	function handleRedPacket(ev) {
		messageItem.value = ev
		api.news.getRedPacketInfo({
			query: {
				// 红包id
				redPacketId: ev.callbackData.callback_json[0].businessId
			}
		}).then(rs => {
			if (rs.code == 200) {
				proxy.$refs.RedPacketRef.open()
				Object.assign(redPacket, rs.data)
				return
			}
			util.alert({
				content: rs.msg,
				showCancel: false,
			})
		})
	}

	// 领取红包
	function handleOpenReadPacket() {
		// 如果不能领取
		if (redPacket.redStatus == false) return
		// 红包过期
		// if (redPacket.isStale == 1) return

		// 抢红包
		api.news.getRedPacket({
			query: {
				// 红包id
				redPacketId: redPacket.id,
				// 领取人id
				userId: userinfo.value.id,
				// 群聊类型
				sendType: {
					'C2C': '1',
					'GROUP': '2',
				} [msg.type],
			}
		}).then(rs => {
			if (rs.code == 200) {
				// 修改领取状态
				redPacket.redStatus = false
				// 获取金额
				redPacket.amount = rs.data
				return
			}
			util.alert({
				content: rs.msg,
				showCancel: false,
			})
		})
	}

	// 选择的emoji
	function emojiTap(val) {
		content.value = content.value + val
	}

	// 点击工具栏
	function handleTool(val) {
		if (toolStatus.value === val) toolStatus.value = 'input'
		else toolStatus.value = val
	}

	// 获取更多消息记录
	function getMoreHistroy() {
		// 获取第一条消息记录
		if (list.total <= list.data.length) return
		getHistory({
			msgId: list.data[0].id
		})
	}

	/**
	 * 获取历史记录
	 * @param {Object} param
	 */
	function getHistory(param = {}) {
		// 验证sdk是否准备完毕
		// let isReady = uni.$chat.isReady();
		// if (!isReady && userinfo.value.id) {
		// 	setTimeout(function() {
		// 		getHistory()
		// 	}, 200);
		// 	return
		// }
		loading.value = true
		console.log('getHistory', msg, `${msg.type}${msg.id}`)

		// 获取历史记录
		getHistoryMsg({
			conversationID: `${msg.type}${msg.id}`,
		}).then(res => {
			console.log('getHistoryMsg', res)
			if (res.code === 0) {
				// 结果
				const result = res.data
				if (!list.nextReqMessageID) list.messageList.length = 0
				// 下次拉取的消息id
				list.nextReqMessageID = result.nextReqMessageID
				// 是否拉取完毕
				list.isCompleted = result.isCompleted
				// 消息体
				list.messageList = result.messageList.map(item => {
					console.log('msg item', item)
					return item
				})

				nextTick(() => {
					param.callback && param.callback()
				})
				return
			}
			util.alert({
				content: res.msg,
				showCancel: false,
			})
		}).catch(rs => {
			console.log('err', rs)
		}).finally(() => {
			loading.value = false
		})
	}

	// 滚动至底部
	function scrollToBottom() {
		uni.createSelectorQuery().in(proxy).select('#scroll-content').boundingClientRect((res) => {
			top.value = res.height

			uni.pageScrollTo({
				scrollTop: top.value,
				duration: 0
			})
			// console.log('top.value', top.value)
		}).exec();
	}

	// 防抖
	function debounce(func, wait = 500) {
		let timeout = null;
		return function(...args) {
			clearTimeout(timeout)
			timeout = setTimeout(() => {
				func.apply(this, args)
			}, wait);
		}
	}

	// 输入框聚焦
	function onFocus() {
		handleTool('input')
	}

	// 输入语音
	function voiceSend(message) {
		console.log('handlePlusSend', message)
		sendMsg(message)
	}

	// 监听滚动
	const handleScroll = (e) => {
		if (e.detail.scrollTop === 0) {
			getHistory()
		}
	}

	// 撑起键盘的高度 打开该元素
	const showGhost = ref(false)
	// 给元素加高度
	const ghostBox = ref({
		height: '0px',
		duration: '0.25s'
	})

	// 监听键盘高度变化 
	function keyboardheightchange(res) {
		ghostBox.value = res.detail
		nextTick(() => {
			showGhost.value = res.detail.height > 0 ? true : false
		})
	}

	/**
	 * 看视频
	 * @param {Object} item 聊天消息对象
	 */
	function handleViewVideo(item) {
		videoUrl.value = item.payload.videoUrl
		// 进入全屏
		videoContext.value.requestFullScreen()
	}

	// 监听视频是否全屏
	function onScreenChange(ev) {
		if (!ev.fullScreen) videoContext.value.pause()
	}

	/**
	 * 更多
	 * @param {Object} ev
	 */
	function handleMore(ev) {
		// 配置
		const url = {
			'GROUP': util.setUrl('/pages/news/detail/group', {
				groupId: msg.id,
			}),
			'C2C': util.setUrl('/pages/index/videoHome', {
				userId: msg.id,
			})
		} [msg.type]

		// 跳转详情
		uni.navigateTo({
			url,
		})
	}
</script>

<template>
	<apex :title="pageTitle">
		<template #right>
			<view>
				<uni-icons type="more-filled" size="40rpx" @click="handleMore" />
			</view>
		</template>
	</apex>

	<view class="app">
		<scroll-view class="scroll-view" scroll-y :scroll-with-animation="true" :scroll-top="top"
			@scroll="onContentScroll" @scrolltoupper="getMoreHistroy">
			<view id="scroll-content" style="padding: 30rpx 30rpx">
				<view v-for="(item, index) in list.messageList" :key="index">
					<!-- 系统消息 -->
					<template v-if="item.from == 'administrator'"></template>
					<!-- 群提示消息 -->
					<template v-else-if="TencentCloudChat.TYPES.MSG_GRP_TIP == item.type">
						<template v-if="item.payload.operationType == 1">
							<template v-if="item.payload.memberList">
								<view class="systemMsg">
									<text>{{item.payload.operatorInfo.nick}} 邀请</text>
									<text class="ml10"
										v-for="(user,index) in item.payload.memberList">{{user.nick}}</text>
									<text class="ml10">加入群聊</text>
								</view>
							</template>
							<template v-else>
								<view class="systemMsg">{{item.payload.operatorInfo.nick}} 加入了群聊</view>
							</template>
						</template>
						<template v-else-if="item.payload.operationType == 2">
							<view class="systemMsg">{{item.payload.operatorInfo.nick}} 退出了群聊</view>
						</template>
						<template v-else-if="item.payload.operationType == 3">
							<view class="systemMsg">
								<text>{{item.payload.operatorInfo.nick}} 已将</text>
								<text class="ml10" v-for="(user,index) in item.payload.memberList">{{user.nick}}</text>
								<text class="ml10">移出群聊</text>
							</view>
						</template>
						<template v-else-if="item.payload.operationType == 4">
							<view class="systemMsg">有群成员被设为管理员</view>
						</template>
						<template v-else-if="item.payload.operationType == 5">
							<view class="systemMsg">有群成员被撤销管理员</view>
						</template>
						<template v-else-if="item.payload.operationType == 6">
							<view class="systemMsg">
								<text>{{item.payload.operatorInfo.nick}} 修改了群</text>
								<template v-if="item.payload.newGroupProfile.avatar">
									<text>头像</text>
								</template>
								<template v-else-if="item.payload.newGroupProfile.groupName">
									<text>名称为 {{item.payload.newGroupProfile.groupName}}</text>
								</template>
								<template v-else>
									<text>资料</text>
								</template>
								<text></text>
							</view>
						</template>
						<template v-else-if="item.payload.operationType == 7">
							<view class="systemMsg">群成员禁言</view>
						</template>
					</template>
					<!-- 群系统通知消息 -->
					<template v-else-if="TencentCloudChat.TYPES.MSG_GRP_SYS_NOTICE == item.type">
					</template>
					<!-- 普通消息 -->
					<template v-else>
						<view class="message" :class="[item.from == userinfo.id ? 'self' : 'friend']">
							<image :src="item.avatar" class="avatar wh80" mode="aspectFill" />

							<view class="df fdc mlr20">
								<!-- 昵称 -->
								<view class="df fdc c999 f20" v-if="item.from != userinfo.id && msg.type == 'GROUP'">
									<view class="name">{{ item.nick }}</view>
								</view>
								<!-- 消息 -->
								<newsTemplate :item="item" :msg="msg" @openRedBag="handleRedPacket"
									@viewVideo="handleViewVideo" />
							</view>
						</view>
					</template>
				</view>
				<view v-if="showGhost" :style="{ height: `${ghostBox.height}px`, transition: `${ghostBox.duration}s` }">
				</view>
				<view class="ghost" :style="{ height: toolHeight + 'px' }"></view>
			</view>
		</scroll-view>
	</view>

	<view class="tool bfff" id="tool">
		<view class="tool-group">
			<!-- 语音 -->
			<image src="/static/news-voice.png" mode="widthFix" class="thumb" @click="handleTool('voice')"></image>
			<!-- 摁住说话 -->
			<template v-if="toolStatus == 'voice'">
				<JyVoice @send="voiceSend" :msg="msg" />
			</template>
			<!-- 输入框 -->
			<template v-if="toolStatus != 'voice'">
				<uni-easyinput @focus="onFocus" type="text" v-model="content" :clearable="false" class="input"
					:adjust-position="false" @keyboardheightchange="keyboardheightchange" placeholder="请输入你的问题"
					confirmType="发送" :focus="inputFocus" />
			</template>
			<!-- 表情 -->
			<image src="/static/news-emoji.png" mode="widthFix" class="thumb" @click="handleTool('emoji')"></image>
			<!-- 加号 -->
			<template v-if="!content">
				<image src="/static/news-plus.png" mode="widthFix" class="thumb" @click="handleTool('plus')" />
			</template>
			<!-- 文本发送按钮 -->
			<template v-else>
				<view class="send" @click="handleSend">发送</view>
			</template>
		</view>
		<view v-if="showGhost" :style="{ height: `${ghostBox.height}px`, transition: `${ghostBox.duration}s` }"></view>
		<!-- 表情 -->
		<template v-if="toolStatus == 'emoji'">
			<emoji @setEmoj="emojiTap"></emoji>
		</template>
		<!-- 加号 -->
		<template v-if="toolStatus == 'plus'">
			<JyPlus @send="handlePlusSend" :msg="msg"></JyPlus>
		</template>
	</view>

	<!-- 视频 -->
	<video :src="videoUrl" id="video" @fullscreenchange="onScreenChange" />

	<!-- 红包封面 -->
	<uni-popup ref="RedPacketRef" type="center">
		<view class="red-bag br20" @touchmove.stop.prevent="">
			<view class="rbag_top">
				<view class="user fmid">
					<view class="avatar">
						<image class="wh80 cir" :src="redPacket.fromUrl" mode="scaleToFill" />
					</view>
					<view class="ml15 f32">{{ redPacket.fromName }}的红包</view>
				</view>
				<view class="app_name mt15 mlr30 tac f40">{{ redPacket.blessing }}</view>
				<!--  -->
				<view class="cfff f32 tac mt50" v-if="redPacket.isStale == 1">红包已过期</view>
				<view class="cfff f32 tac mt50" v-else-if="redPacket.remainingCount == 0">来晚啦,红包已被抢完</view>

				<!-- redPacket.redStatus true可以领取 false不可领取 -->
				<view class="amount f32" v-if="!redPacket.redStatus">
					<text class="">已领取</text>
					<text class="value">{{ redPacket.amount }}</text>
					<text class="unit" v-if="redPacket.payType == 1">余额</text>
					<text class="unit" v-else-if="redPacket.payType == 2">积分</text>
				</view>
			</view>

			<view class="open_rbag_btn pr fmid" @click="handleOpenReadPacket">
				<text v-if="redPacket.amount">已</text>
				<text>开</text>
			</view>
		</view>

		<view class="tac mt35" @click.stop="$refs.RedPacketRef.close()">
			<uni-icons type="close" color="#fbd977" size="32" />
		</view>
	</uni-popup>
</template>


<style lang="scss" scoped>
	@import './index.scss';

	// 
	#video {
		position: fixed;
		top: 100%;
		left: 0;
	}

	// 系统消息
	.systemMsg {
		margin: 30rpx 0;
		text-align: center;
		color: #999;
		font-size: 22rpx;
	}

	// 
	.red-bag {
		position: relative;
		width: 528rpx;
		height: 60vh;
		color: #ECCD97;
		background-color: #e0534a;
		box-shadow: 0 0 20rpx #00000033;

		.rbag_top {
			padding-top: 60rpx;
			height: 70%;
			background-color: #e0534a;
			border-radius: 0 0 500rpx 500rpx / 0 0 200rpx 200rpx;
			box-shadow: 0 5rpx 5rpx rgba(0, 0, 0, 0.2);

			.amount {
				margin-top: 120rpx;
				text-align: center;
				letter-spacing: 1rpx;

				.value {
					font-size: 60rpx;
					font-weight: bold;
				}
			}
		}

		.open_rbag_btn {
			width: 180rpx;
			height: 180rpx;
			margin: -90rpx auto 0;
			color: #fef5e8;
			font-size: 74rpx;
			font-weight: bold;
			background-color: #ffd287;
			box-shadow: 2rpx 2rpx 6rpx rgba(0, 0, 0, 0.2);
			border-radius: 50%;
			z-index: 1;
		}

		// 打开红包
		.open_rbag_model {
			position: fixed;
			top: 0;
			left: 0;
			width: 100%;
			height: 100vh;
			background-color: rgba(0, 0, 0, 0.3);
			z-index: 1000;

			.rbag_conbg {
				position: absolute;
				top: 0;
				left: 0;
				right: 0;
				bottom: 0;
				width: 80%;
				height: 840rpx;
				margin: auto;
				z-index: 1001;
			}

			.open_rbag_con {
				z-index: 1002;

				.open_title {
					height: 120rpx;
					line-height: 120rpx;
					text-align: center;
					font-size: 38rpx;
					letter-spacing: 2rpx;
					color: #e46965;
				}

				.rbag_detail {
					margin-top: 90rpx;

					.open_money {
						text-align: center;
						font-size: 80rpx;
						color: #c95948;
						font-weight: bold;
						display: flex;
						justify-content: center;

						.danwei {
							font-size: 30rpx;
							margin-left: 16rpx;
							margin-top: 24rpx;
						}
					}

					.open_tips {
						text-align: center;
						font-size: 30rpx;
						color: #d26762;
						margin-top: 30rpx;
					}
				}

				.lookbag_box {
					margin-top: 300rpx;
					display: flex;
					justify-content: center;

					.lookbag_btn {
						width: 70%;
						height: 90rpx;
						line-height: 90rpx;
						text-align: center;
						font-size: 32rpx;
						color: #c95948;
						letter-spacing: 2rpx;
						background-color: #ffd356;
						border-radius: 50rpx;
						box-shadow: 0rpx 0rpx 4rpx rgba(0, 0, 0, 0.2);
					}
				}

				.hide_btn {
					position: absolute;
					bottom: -110rpx;
					left: 0;
					right: 0;
					width: 80rpx;
					height: 80rpx;
					line-height: 80rpx;
					text-align: center;
					margin: 0 auto;
				}
			}
		}
	}
</style>