<template>
	<view class="container">
		<view id="topnav" class="topnav flex-start"
			:style="{ 'height': `${topbarOffsetHeight - statusBarHeight}px`, 'padding-top': `${statusBarHeight}px` }">
			<view class="nav-item flex-center" @click="back">
				<image :src="`${assetsUrl}back.png`" mode="widthFix" class="nav-img"></image>
			</view>
			<view class="nav-center flex-center">
				<view class="nav-text font32 fw600">
					{{ userInfo.nick }}
				</view>
				<view class="nav-tip font20 fw400">
					<text></text>{{ onlineState }} · {{ userInfo.distance }}
				</view>
			</view>

			<view class="nav-item"></view>
		</view>
		<view class="message-list" :style="[{ 'height': `${scrollHeight}px`, 'margin-top': `${topbarOffsetHeight}px` }]">
			<!-- <view class="message-list" :style="[messageStyle]"> -->
			<TUI-message-list id="message-list" ref="messageList" :conversation="conversation" :scrollHeight="scrollHeight"
				:topbarOffsetHeight="topbarOffsetHeight" />
		</view>
		<view class="talk-box" :style="[{ 'bottom': `${bottomVal}px` }]" id="talk-box" @touchmove="prevent()">
			<view class="input-box flex-between">
				<!-- <van-field v-model="inputText"  label="文本"  placeholder="请输入消息…" /> -->
				<!-- <input type="text" class="input" confirm-type="send" placeholder="请输入消息…" :adjust-position="true" v-model="inputText" placeholder-style="color:#7D7DA4 ;font-size:24rpx" @confirm="sendTextMessage"> -->
				<input class="TUI-message-input-area" :adjust-position="false" cursor-spacing="20" v-model="inputText"
					@confirm="sendTextMessage" maxlength="140" type="text" placeholder-class="input-placeholder" placeholder-style="color:#7D7DA4 ;font-size:24rpx"
					placeholder="请输入消息…" @focus="inputBindFocus" @blur="inputBindBlur" />
				<view class="input-btn font22 fw400" @click="sendTextMessage">
					发送
				</view>
			</view>
			<view class="action-box flex-between">
				<image :src="`${assetsUrl}talk-voice.png`" mode="aspectFit" class="act-img" @click="showActionPanel(0)"></image>
				<image :src="`${assetsUrl}talk-pic.png`" mode="aspectFit" class="act-img" @click="showActionPanel(1)"></image>
				<image :src="`${assetsUrl}talk-video.png`" mode="aspectFit" class="act-img" @click="showActionPanel(2)"></image>
				<image :src="`${assetsUrl}talk-emo.png`" mode="aspectFit" class="act-img" @click="showActionPanel(3)"></image>
			</view>
			<view class="action-panel" :style="{ 'padding-bottom': `${showActionIndex === -1 ? '68rpx' : '20rpx'}` }">
				<view class="voice-panel flex-center" v-if="showActionIndex === 0">
					<view class="voice-text font22 fw400">
						{{ voiceText }}
					</view>
					<image :src="`${assetsUrl}talk-voice-${isRecording ? 'delete' : 'open'}.png`" mode="aspectFill" class="voice-img"
						@longpress="handleLongPress" @touchmove="handleTouchMove" @touchend="handleTouchEnd"></image>
				</view>
				<view class="emoji-box" v-if="showActionIndex === 3">
					<TUI-Emoji @enterEmoji="appendMessage"></TUI-Emoji>
				</view>
			</view>
		</view>
		<view v-if="videoPlay" class="container-box" @tap.stop="stopVideoHander">
			<video v-if="videoPlay" class="video-message" :src="videoMessage.payload.videoUrl || videoMessage.videoUrl"
				:poster="videoMessage.payload.thumbUrl || videoMessage.videoCover" object-fit="cover" error="videoError"
				autoplay="true" direction="0" show-fullscreen-btn="false"
				:style="{ 'width': `${videoMessage.payload.thumbWidth || videoMessage.width}px`, 'height': `${videoMessage.payload.thumbHeight || videoMessage.height}px` }" />
		</view>
	</view>
</template>

<script>
import TUIEmoji from '../../components/tui-chat/message-elements/emoji/index';
import TUIMessageList from '../../components/tui-chat/message-list/index';

export default {
	components: {
		TUIMessageList,
		TUIEmoji
	},
	data() {
		return {
			assetsUrl: this.$util.assetsUrl,
			scrollHeight: 0,
			topNavHeight: 0,
			userInfo: null,
			messageList: [],
			message: null,//消息实例
			onlineState: '',
			scrollRefreshing: false,
			scrollTriggered: true,
			conversation: '',
			conversationID: '',
			inputText: '',
			showSendBtn: false,
			showActionIndex: -1,
			recorderManager: null,
			voiceText: '按住说话，松手发送',
			recordTimeTotal: 60,//最大长度，30秒
			isRecording: false,
			canSend: false,
			startPoint: 0,
			videoPlay: false,
			videoMessage: {},
			bottomVal: 0 // 底部bottom
		}
	},
	computed: {
		statusBarHeight() {
			return this.$store.state.statusBarHeight;
		},
		topbarOffsetHeight() {
			return this.$store.state.topbarOffsetHeight;
		},
		messageStyle() {
			let obj = {
				'height': `${this.scrollHeight}px`,
				'margin-top': `${this.topbarOffsetHeight}px`
			}
			return obj
			// [{,'margin-top':`${topbarOffsetHeight}px`}]
		}
	},
	created() {
		uni.$on('videoPlayerHandler', value => {
			this.videoPlay = value.isPlay;
			this.videoMessage = value.message;
		});
		uni.authorize({
			scope: 'scope.record',
			success: () => {
				this.startRecordManage();
			},
			fail: err => {
				uni.showModal({
					content: '检测到您没打开录音功能权限，是否去设置打开？',
					confirmText: "确认",
					cancelText: '取消',
					success: res => {
						if (res.confirm) {
							uni.openSetting({
								success: ress => {
									if (ress.authSetting) {
										this.startRecordManage();
									}
								}
							})
						}
					}
				})
			}
		})
	},
	onLoad(options) {
		this.conversationID = options.conversationid;
		uni.$TUIKit.setMessageRead({
			conversationID: this.conversationID
		})
		uni.$TUIKit.getConversationProfile(this.conversationID).then(res => {
			const { conversation } = res.data;
			this.conversation = conversation;
			console.log(this.conversation)
		});
		let pages = getCurrentPages();
		let prePage = pages[pages.length - 2];
		this.userInfo = prePage.$vm.userInfo;

	},
	mounted() {

		if (this.userInfo.lastActiveTime === 0 || this.userInfo.online) {
			this.onlineState = '在线';
		}
		else if (this.userInfo.lastActiveTime < 30 && !this.userInfo.online) {
			this.onlineState = '刚刚';
		}
		else {
			this.onlineState = '离线';
		}
		setTimeout(() => {
			this.computedScollviewHeight();
		}, 500)


	},
	methods: {
		inputBindFocus(e) {
			// 获取手机键盘的高度，赋值给input 所在盒子的 bottom 值
			// 注意!!! 这里的 px 至关重要!!! 我搜到的很多解决方案都没有说这里要添加 px
			// this.$emit('changeBottomVal',  e.detail.height + 'px')
			this.scrollHeight = e.detail.height
			this.bottomVal = e.detail.height
			console.log(e.detail.height, 'e.detail.height', e, 'this.scrollHeight', this.scrollHeight)
		},

		inputBindBlur() {
			// input 失去焦点，键盘隐藏，设置 input 所在盒子的 bottom 值为0
			// this.$emit('changeBottomVal', 0)
			this.scrollHeight = 0
			this.bottomVal = 0

		},
		back() {
			uni.navigateBack({
				delta: 1
			})
		},
		prevent() {
			return false;
		},

		stopVideoHander() {
			this.videoPlay = false;
		},
		/**
		 * 计算scroll高度
		 */
		computedScollviewHeight() {
			let query = uni.createSelectorQuery().in(this);
			let heightLeaf = 0;
			query.selectAll('#topnav,#talk-box').boundingClientRect(data => {
				data.forEach(item => {
					heightLeaf += item.height;
				})
			}).exec(() => {
				let sysInfo = uni.getSystemInfoSync();
				this.scrollHeight = sysInfo.windowHeight - heightLeaf;
				this.$refs.messageList.scrollToButtom();
			});

		},
		/**
		 * 推荐下拉刷新、加载更多
		 */
		scrollRefresh() {
			if (this.scrollRefreshing) {
				return;
			}
			this.scrollRefreshing = true;
			setTimeout(() => {
				this.scrollTriggered = false;
				this.scrollRefreshing = false;
			}, 1000);
			this.isLoadPreData = true;

		},
		scrollPulling(e) { },
		scrollRestore() { this.scrollTriggered = true; },
		scrollAbort() { },
		scrollToBottom() { },
		showActionPanel(index) {
			if (this.showActionIndex === index) {
				this.showActionIndex = -1;
				setTimeout(() => {
					this.computedScollviewHeight();
				}, 50)
				return;
			}

			switch (index) {
				case 0:
					this.showActionIndex = index;
					setTimeout(() => {
						this.computedScollviewHeight();
					}, 50)
					break;
				case 1:
					this.showActionIndex = -1;
					uni.chooseImage({
						count: 1,
						sizeType: ['original', 'compressed'],
						sourceType: ['album', 'camera'],
						success: res => {
							console.log(res)
							const message = uni.$TUIKit.createImageMessage({
								to: String(this.userInfo.id),
								conversationType: this.conversation.type,
								payload: {
									file: res
								},
								onProgress: event => { }
							});
							this.$sendTIMMessage(message);
						}
					})
					break;
				case 2:
					uni.chooseVideo({
						sourceType: ['album', 'camera'],
						maxDuration: 60,
						camera: 'back',
						success: res => {
							const message = uni.$TUIKit.createVideoMessage({
								to: String(this.userInfo.id),
								conversationType: this.conversation.type,
								payload: {
									file: res
								},
								onProgress: event => { }
							});
							this.$sendTIMMessage(message);
						}
					})
					break;
				case 3:
					this.showActionIndex = index;
					setTimeout(() => {
						this.computedScollviewHeight();
					}, 50)
					break;
			}

		},
		appendMessage(e) {
			this.inputText += e.detail.message;
		},
		startRecordManage() {
			// 加载声音录制管理器
			this.recorderManager = uni.getRecorderManager();
			console.log(this.recorderManager)
			this.recorderManager.onStop(res => {
				console.log(res)
				clearInterval(this.recordTimer);
				// 兼容 uniapp 打包app，duration 和 fileSize 需要用户自己补充
				// 文件大小 ＝ (音频码率) x 时间长度(单位:秒) / 8
				let msg = {
					duration: res.duration ? res.duration : this.recordTime * 1000,
					tempFilePath: res.tempFilePath,
					fileSize: res.fileSize ? res.fileSize : ((48 * this.recordTime) / 8) * 1024
				};
				uni.hideLoading();
				// 兼容 uniapp 语音消息没有duration
				if (this.canSend) {
					if (msg.duration < 1000) {
						uni.showToast({
							title: '录音时间太短',
							icon: 'none'
						});
					} else {
						// res.tempFilePath 存储录音文件的临时路径
						const message = uni.$TUIKit.createAudioMessage({
							to: String(this.userInfo.id),
							conversationType: this.conversation.type,
							payload: {
								file: msg
							}
						});
						this.$sendTIMMessage(message);
					}
				}
				this.startPoint = 0;
				this.isRecording = false;
				this.canSend = true;
				this.voiceText = '按住说话，松手发送';
			});
			this.recorderManager.onError(err => {
				console.log(err)
			})
		},
		handleLongPress(e) {
			uni.vibrateShort();
			this.recorderManager.start({
				duration: 60000,
				// 录音的时长，单位 ms，最大值 600000（10 分钟）
				sampleRate: 44100,
				// 采样率
				numberOfChannels: 1,
				// 录音通道数
				encodeBitRate: 192000,
				// 编码码率
				format: 'aac' // 音频格式，选择此格式创建的音频消息，可以在即时通信 IM 全平台（Android、iOS、微信小程序和Web）互通
			});
			this.startPoint = e.touches[0];
			this.voiceText = '正在录音,上划可取消';
			this.isRecording = true;
			this.recordTime = 0;
			this.recordTimer = setInterval(() => {
				this.recordTime++;
				if (this.recorTime >= this.recordTimeTotal) {
					this.recorderManager.stop();
					clearInterval(this.recordTimer);
					this.recordTimer = null;
				}
			}, 1000);
		},

		// 录音时的手势上划移动距离对应文案变化
		handleTouchMove(e) {
			if (this.isRecording) {
				if (this.startPoint.clientY - e.touches[e.touches.length - 1].clientY > 100) {
					this.voiceText = '松开手指，取消发送';
					this.canSend = false;
				} else if (this.startPoint.clientY - e.touches[e.touches.length - 1].clientY > 20) {
					this.voiceText = '上划可取消';
					this.canSend = true;
				} else {
					this.voiceText = '抬起停止';
					this.canSend = true;
				}
			}
		},

		// 手指离开页面滑动
		handleTouchEnd() {
			this.isRecording = false;
			this.voiceText = '按住说话，松手发送';
			uni.hideLoading();
			this.recorderManager.stop();
		},
		sendTextMessage() {
			const to = String(this.userInfo.id);
			const text = this.inputText;
			const message = uni.$TUIKit.createTextMessage({
				to,
				conversationType: this.conversation.type,
				payload: {
					text
				}
			});
			this.inputText = '';
			this.$sendTIMMessage(message);
		},
		$sendTIMMessage(message) {

			uni.$TUIKit.sendMessage(message).then((res) => {
				this.$EventBus.$emit('sendMessage', message)
				this.$refs.messageList.scrollToButtom();
			}).catch((error) => {
				uni.showToast({
					title: '发送消息失败',
					icon: "none"
				})
			})
		},

	}
}
</script>

<style lang="scss" scoped>
.container {
	width: 100vw;
	height: 100vh;
	background-color: $bgcolor1;
	position: relative;
	overflow: hidden;

	.topnav {
		padding: 0 10rpx;
		position: fixed;
		top: 0;
		left: 0;
		width: 100vw;
		z-index: 100;
		background-color: $bgcolor1;

		.nav-item {
			width: 40rpx;
			height: 40rpx;
			margin-left: 16rpx;

			.nav-img {
				width: 40rpx;
				height: 40rpx;
			}
		}

		.nav-center {
			flex: 1;
			flex-direction: column;

			.nav-text {

				color: $fontcolor5;
				height: 40rpx;
				text-align: center;
			}

			.nav-tip {
				color: $fontcolor2;
			}
		}

	}

	.talk-box {
		position: fixed;
		bottom: 0;
		left: 0;
		width: 100vw;
		padding-top: 16rpx;
		background-color: $bgcolor1;

		.input-box {
			margin: 0rpx 32rpx;
			height: 80rpx;
			border-radius: 80rpx;
			background-color: $bgcolor4;
			padding: 0 24rpx;

			.input {
				width: 100%;
				height: 100%;
				color: #ffffff;
				font-size: 22rpx;
			}

			.input-btn {
				background-color: $primary;
				color: #ffffff;
				border-radius: 16rpx;
				height: 56rpx;
				line-height: 56rpx;
				width: 120rpx;
				text-align: center;

			}
		}

		.action-box {
			padding: 0rpx 0rpx 20rpx 0rpx;
			margin: 0 90rpx;
			margin-top: 36rpx;

			.act-img {
				width: 56rpx;
				height: 56rpx;
			}
		}

		.action-panel {
			width: 100vw;

			.voice-panel {
				height: 400rpx;
				flex-direction: column;

				.voice-text {
					color: #7D7DA4;
					text-align: center;

				}

				.voice-img {
					width: 200rpx;
					height: 200rpx;
					margin-top: 40rpx;
				}
			}
		}

		.emoji-box {
			padding: 0 11rpx;
			box-sizing: border-box;
			height: 400rpx;
			flex-wrap: wrap;
			transition: height .3s;

			.emoji-item {
				width: 64rpx;
				height: 64rpx;
				padding: 20rpx;

				.emoji-img {
					width: 64rpx;
					height: 64rpx;
				}
			}
		}
	}

	.container-box {
		position: fixed;
		display: flex;
		justify-content: center;
		align-items: center;
		left: 0;
		right: 0;
		bottom: 0;
		top: 0;
		background-color: rgba(0, 0, 0, 0.5);

		.video-message {
			width: 90vw;
			height: auto;
		}
	}
}</style>

