<template>
	<!-- 聊天底部栏组件 -->
	<view class="chat-chat-btn-cn">
		<!-- 组件内容 -->
		<view class="cn-content">

			<!-- 底部栏 -->
			<!-- :style="{bottom: 'calc(' + keyboardHeight + 'rpx)'}" -->
			<view class="jc-footer-safe border-top-ed bg-f7">
				<view class="padding-tb-15 flex align-end" :style="{height: bottomBarHight + 'rpx'}">

					<!-- 左侧 切换图标 -->
					<view class="line-height-70 text-center" style="width: 90rpx;">
						<!-- 切换为语音图标 -->
						<text class="tyIcon-xingzhuangjiehe text-98 text-50"
							v-if="sendType == 1 || sendType == 3 || sendType == 4" @click="sendTypeChange(2)"></text>
						<!-- 切换为文本图标 -->
						<text class="tyIcon-jianpan1 text-98 text-50" v-if="sendType == 2"
							@click="sendTypeChange(1)"></text>
					</view>

					<!-- 中间 文本框
					高度最高展示10行
					@keyboardheightchange事件只有微信小程序兼容 @keyboardheightchange="keyboardHeightChange"-->
					<textarea class="flex-one padding-lr-20 padding-tb-15 line-40 radius-10 bg-ff"
						:style="{height: textareaHighet + 'rpx'}" :show-confirm-bar="false" cursor-spacing="100"
						maxlength="-1" v-model="content" :focus="isTextareaFocus" @focus="focus" @blur="blur"
						@linechange="textAreaLineChange" @click="sendTypeChange(1)"
						v-if="sendType == 1 || sendType == 3 || sendType == 4"></textarea>

					<!-- 中间 发送语音按钮 -->
					<view class="flex-one line-height-70 radius-10 bg-ff text-center text-28" @touchstart="touchStart"
						@touchend="touchEnd" @touchmove="touchMove" v-if="sendType == 2">
						{{voiceText}}
					</view>

					<!-- 右侧 更多发送类型 -->
					<view class="padding-lr-20 flex align-center justify-between">
						<!-- emoji图标 -->
						<view class="margin-right-20 line-height-70" style="width: 50rpx;">
							<!-- 切换为表情图标 -->
							<text class="tyIcon-biaoqing text-98 text-50" v-if="sendType != 4"
								@click="sendTypeChange(4)"></text>
							<!-- 切换为文本图标 -->
							<text class="tyIcon-jianpan1 text-98 text-50" v-if="sendType == 4"
								@click="sendTypeChange(1)"></text>
						</view>
						<!-- <image v-if="is_need_emoji === true" class="smil" src="/static/smil.png"></image> -->

						<!-- 加号图标 选择图片 -->
						<view class="line-height-70" style="width: 50rpx;"
							v-if="!((sendType == 1 || sendType == 4) && content !== '')" @click="sendTypeChange(3)">

							<text class="tyIcon-tianjia text-98 text-50"></text>

						</view>

						<!-- 发送图标 选择图片 -->
						<view class="width-100 line-height-50 radius-6 bg-main text-center text-26 text-ff"
							v-if="(sendType == 1 || sendType == 4) && content !== ''" @click="sendMessage(1)">
							发送
						</view>
					</view>
				</view>

				<!-- 其他未展示类型功能 不是浮层方式 底部栏下方 显示或隐藏-->
				<view class="send-type-other bg-f7 border-top-ed" style="padding-top: 78rpx;height: 330rpx;"
					v-if="sendType == 3">
					<view class="flex align-center flex-wrap justify-around" style="padding: 0 90rpx;">
						<view class="other-type-item" @click="chooseImage('album')">
							<view class="icon-block">
								<text class="tyIcon-tu line-110 text-50 text-4d"></text>
							</view>
							<view class="margin-top-30 text-24 text-80">相册</view>
						</view>
						<view class="other-type-item" @click="chooseImage('camera')">
							<view class="icon-block">
								<text class="tyIcon-paizhao line-110 text-50 text-4d"></text>
							</view>
							<view class="margin-top-30 text-24 text-80">拍摄</view>
						</view>
						<view class="other-type-item" @click="chooseLocation()">
							<view class="icon-block">
								<text class="tyIcon-weizhi line-110 text-50 text-4d"></text>
							</view>
							<view class="margin-top-30 text-24 text-80">位置</view>
						</view>
					</view>
				</view>

				<!-- emoji表情 不是浮层方式 底部栏下方 显示或隐藏 -->
				<view class="send-type-other bg-f7 border-top-ed" v-if="sendType == 4">
					<ty-utils-emoji-list @emojiAdd="emojiAdd"></ty-utils-emoji-list>
				</view>

			</view>
		</view>

		<!-- 组件浮层 -->
		<view class="cn-layer">

			<!-- 录音中状态，显示浮层 -->
			<view v-if="sendType == 2 && recordStatus == 1">
				<ty-layer-pop-up :overlay="false">
					<view @click.stop="">
						<view class="voice-record1">
							<image class="jc-image-280" src="../../../static/chat/voice.gif"></image>
						</view>
					</view>
				</ty-layer-pop-up>
			</view>

			<!-- 录音中状态，录音时长剩下不到10s，显示浮层 -->
			<view v-if="sendType == 2 && recordStatus == 2">
				<ty-layer-pop-up :overlay="false">
					<view @click.stop="">
						<view class="voice-record flex flex-direction align-center">
							<view class="text-ff" style="height: 208rpx; line-height: 208rpx; font-size: 160rpx;">
								{{maxRecordSeconds-recordSeconds}}
							</view>
							<view class="text-24 text-ff">手指上滑，取消发送</view>
						</view>
					</view>
				</ty-layer-pop-up>
			</view>

			<!-- 录音时长太短，小于1s -->
			<view v-if="sendType == 2 && showSpeechShortLayer">
				<ty-layer-pop-up :overlay="false">
					<view @click.stop="">
						<view class="voice-record flex flex-direction align-center">
							<view class="margin-top-40" style="height: 128rpx;">
								<text class="tyIcon-zhuyi text-ff"
									style="line-height: 128rpx;font-size: 128rpx;"></text>
							</view>
							<view class="margin-top-40 text-24 text-ff">说话时间太短</view>
						</view>
					</view>
				</ty-layer-pop-up>
			</view>
		</view>
	</view>
</template>

<script>
	import record from '@/components/hzjc/utils/functions/record.js'
	import image from '@/components/hzjc/utils/functions/image.js'
	// #ifdef H5
	let jweixin = require('jweixin-module')
	// #endif
	// #ifdef APP-PLUS|MP-WEIXIN
	const recorderManager = uni.getRecorderManager()
	// #endif
	export default {
		props: {

		},
		data() {
			return {
				// 底部栏高度
				bottomBarHight: 100,
				// 文本框高度
				textareaHighet: 70,
				keyboardHeight: 0,

				// 发送方式 1--文字 2--语音 3--其他类型发送浮层 4--emoji表情
				sendType: 1,

				// 输入文本
				content: '',
				// 录音文件地址
				voiceUrl: '',
				// 图片路径
				imageUrl: '',

				// 输入文本时，输入行数
				textLine: 1,
				// 输入文本时，文本框是否聚焦
				isTextareaFocus: false,

				// 录音状态 0--未开始 1--录音中 2--录音时长剩下不到10s
				recordStatus: 0,
				// 录音时长
				recordSeconds: 0,
				// 最长录音时长
				maxRecordSeconds: 60,
				// 显示录音时长
				// showRecordSeconds: 0,
				// 语音提示文案
				voiceText: '按住 说话',
				// 是否显示说话太短浮层
				showSpeechShortLayer: false,

				// 定时器 - 录音每秒倒计时
				recordIntervalTimer: '',
				// 定时器 - 录音执行延时
				recordTimeOutTimer: '',

				// 录音开始时间
				recordStartTime: '',
				// 手势是否移动
				isTouchMove: false,
				// 移动开始Y轴距离
				touchStartY: 0,
				// 移动结束Y轴距离
				touchEndY: 0,
			}
		},

		created() {
			// #ifdef H5
			// 公众号
			if (this.cn.userAgent() == 'weixin') {

				// 监听录音自动停止接口，超过最大录音时间自动停止
				jweixin.onVoiceRecordEnd({
					success: (res) => {
						console.log('--监听到录音自动结束--')

						// 录音结束之后数据重置
						this.dataResetafterRecordStop()

						// 修改录音状态为结束，浮层消失
						this.recordStatus = 0

						// 当前录音时长为最大数值
						this.recordSeconds = this.maxRecordSeconds

						// 上传录音文件到云端
						record.uploadVoice(res.localId).then(res => {
							// 语音文件路径
							this.voiceUrl = res

							this.sendMessage(2)
						})
					}
				})
			}
			// #endif

			// #ifdef MP-WEIXIN|APP-PLUS
			recorderManager.onError((res) => {
				console.log('recorderManagerOnError', res)
			})

			// 录音停止事件，会回调文件地址
			recorderManager.onStop((res) => {
				console.log('recorderManagerOnStop', res)
				/* res格式
					{duration: 6647.211074829102, tempFilePath: "wxfile://tmp_b93d40bd1e3d53bcbdf7b88e05924f96.mp3", fileSize: 39921} */

				// 录音结束之后数据重置
				this.dataResetafterRecordStop()

				// 获取录音文件的临时路径
				let tempFilePath = res.tempFilePath

				// 上传录音文件到OSS
				record.uploadRecordFile(tempFilePath).then(res => {
					let path = res[0]
					// 录音文件
					this.voiceUrl = path
					// 发送语音消息
					if (this.recordSeconds > 0) {
						this.sendMessage(2)
					}
				})
			})
			// #endif
		},

		methods: {

			/**
			 * 选择是输入文字还是语音
			 * @param {int} type 1--文字 2--语音 3--其他 4--表情
			 * @date 2022-08-10
			 */
			sendTypeChange(type) {
				// 更改发送方式
				this.sendType = type

				// 底部栏下面的块浮层高度
				let otherBlockHeight = 0

				// 文字类型
				if (this.sendType == 1) {
					// 更改底部栏高度 文本框高度+ 上下间距
					this.bottomBarHight = this.textLine * 40 + 30 + 30

					// 文本框聚焦
					this.isTextareaFocus = true
					// 非文字类型
				} else {
					// 文本框固定高度100
					this.bottomBarHight = 100

					// 文本框取消聚焦
					this.isTextareaFocus = false

					if (type == 3) {
						// +展开 类型高度为330
						otherBlockHeight = 330
					} else if (type == 4) {
						// emoji高度为330
						otherBlockHeight = 520
					}
				}

				// 底部栏高度变化事件
				this.$emit('bottomHightChange', {
					// 底部条高度 + 其他块高度（选择图片、选择表情） + 键盘高度
					bottomHight: this.bottomBarHight + otherBlockHeight
				})
			},

			/**
			 * 输入文本框行高发生变化
			 * @param {object} e
			 * @date 2022-08-10
			 */
			textAreaLineChange(e) {
				console.log(8999, e)
				this.textLine = 1

				// 最多显示10行文本
				if (e.detail.lineCount <= 12) {
					// if(this.textLine == 2 && e.detail.lineCount == 4){
					// 	this.textLine = 3;
					// }else if(this.textLine == 6 && e.detail.lineCount == 8){
					// 	this.textLine = 7;
					// }else{
					// 	this.textLine = e.detail.lineCount
					// }
					if (e.detail.lineCount <= 7 && e.detail.lineCount > 3) {
						this.textLine = e.detail.lineCount - 1
					} else if (e.detail.lineCount > 7) {
						this.textLine = e.detail.lineCount - 2
					} else {
						this.textLine = e.detail.lineCount
					}
				} else {
					this.textLine = 10
				}

				// 更改文本框高度 文本高度 + 上下间距
				this.textareaHighet = this.textLine * 40 + 30

				// 更改底部栏高度 文本框高度+ 上下间距
				this.bottomBarHight = this.textLine * 40 + 30 + 30

				// 底部栏高度变化事件
				if (this.textLine > 1) {
					this.$emit('bottomHightChange', {
						bottomHight: this.bottomBarHight
					})
				}
			},

			/**
			 * textarea获得焦点
			 * @date 2022-09-21
			 */
			focus(e) {
				let systemInfo = uni.getSystemInfoSync()
				// console.log(systemInfo.safeAreaInsets)
				this.keyboardHeight = this.cn.px2rpx(e.detail.height - systemInfo.safeAreaInsets.bottom)
			},

			/**
			 * textarea失去焦点
			 * @date 2022-09-21
			 */
			blur(e) {
				this.keyboardHeight = 0
			},

			/**
			 * 开始录音
			 * @param {object} e 
			 * @date 2022-08-10
			 */
			touchStart(e) {
				// 触发开始录音事件
				this.$emit('recordStart')

				// 阻止长按默认事件
				e.preventDefault()

				// 修改展示文案
				this.voiceText = '松开 发送'

				// 清除可能存在的录音
				// record.stopRecord()

				// 录音开始时间
				this.recordStartTime = new Date().getTime()

				// 延迟执行录音事件 防止误点触发录音
				this.recordTimeOutTimer = setTimeout(() => {
					// 判断授权
					record.isAuth().then(res => {
						// 没有授权，调用录音接口弹出授权，并立即停止录音
						if (!res) {
							// #ifdef H5
							if (this.cn.userAgent() == 'weixin') {
								record.record().then(res => {
									record.stopRecord(0).then(res => {
										this.voiceText = '按住 说话'
										uni.setStorageSync('is_auth_record', true)
									})
								}).catch(res => {
									this.voiceText = '按住 说话'
								})
								return false
							}
							// #endif

							// #ifdef MP-WEIXIN
							this.voiceText = '按住 说话'
							return false
							// #endif
						} else {
							/* 修改录音状态为已开始
							在开始录音前就修改,防止在回调的过程中触发endVoive被拦截导致录音不能终止 */
							this.recordStatus = 1

							// 延迟200ms录音，避免发生误点的情况
							record.record().then(res => {

								// 倒计时60s时间
								this.recordIntervalTimer = setInterval(() => {
									// 录音秒数 +1
									this.recordSeconds++

									// 录音时长达到60s
									if (this.recordSeconds >= this.maxRecordSeconds) {
										// 清空读秒定时器
										this.recordStatus = 0;
										clearInterval(this.recordIntervalTimer)

										// that.stopVoiceOrSend(1)
										// 录音秒数只剩10秒钟之内
									} else if (this.recordSeconds >= this
										.maxRecordSeconds - 10) {
										// 更改录音状态
										this.recordStatus = 2
									}
								}, 1000)
							})
						}
					})
				}, 200)
			},

			/**
			 * 手势移动 上滑取消录音
			 * @param {object} e 
			 * @date 2022-08-11
			 */
			touchMove: function(e) {
				// 录音状态，正在录音时，上滑取消录音
				if (this.sendType == 2 && this.recordStatus != 0) {
					// 第一次移动抓取
					if (!this.isTouchMove) {
						// 更改状态为移动中
						this.isTouchMove = true
						// 记录移动开始Y轴距离
						this.touchStartY = e.touches[0].clientY
						// 移动过程中移动抓取
					} else {
						// 实时记录移动Y轴距离，更新移动结束Y轴距离
						this.touchEndY = e.touches[0].clientY
					}
				}
			},

			/**
			 * 结束录音
			 * @param {object} e 
			 * @date 2022-08-10
			 */
			touchEnd(e) {
				// 手势移动距离
				let touchMoveDistance = this.touchStartY - this.touchEndY

				// 录音结束之后数据重置
				this.dataResetafterRecordStop()

				// 300ms以内的误点事件处理
				if (new Date().getTime() - this.recordStartTime < 300) {
					// 清除延迟执行定时
					clearTimeout(this.recordTimeOutTimer)
					return false
				}

				// 如果有当前为未录音状态，一般为自动监听到录音结束事件
				if (this.recordStatus == 0) {
					return false
				}

				// 修改录音状态为结束，浮层消失
				this.recordStatus = 0

				// 向上滑动超过屏幕的五分之一则为取消录音
				const res = uni.getSystemInfoSync()
				if (touchMoveDistance > parseFloat(res.windowHeight) / 5) {
					// 停止录音
					record.stopRecord(0)

					// 录音秒数归0
					this.recordSeconds = 0

					return false
				}

				// 录音时长小于1s
				if (this.recordSeconds < 1) {
					// 停止录音
					record.stopRecord(0)

					// 录音秒数归0
					this.recordSeconds = 0

					// 显示说话太短浮层
					this.showSpeechShortLayer = true
					setTimeout(() => {
						// 1s后关闭说话太短浮层
						this.showSpeechShortLayer = false
					}, 1000)

					return false
				}

				// 结束录音并上传至云端
				record.stopRecord().then(res => {
					// #ifdef H5
					if (this.cn.userAgent() == 'weixin') {
						// 录音文件
						this.voiceUrl = res
						// 发送语音消息
						this.sendMessage(2)
					}
					// #endif

				})
			},

			/**
			 * 选择图片
			 * @param {string} type camera--使用相机  album--从相册选图
			 * @date 2022-08-14
			 */
			chooseImage: function(type) {
				let sourceType = [type]
				image.chooseImageUpload(1, sourceType).then(res => {
					this.imageUrl = res[0]

					// 发送消息
					this.sendMessage(3)
				})
			},

			/**
			 * 选择emoji表情
			 * @param {Object} e
			 * @date 2022-08-10
			 */
			emojiAdd(e) {
				// 文本追加emoji表情
				this.content += e.alt
			},

			/**
			 * 打开地图选择位置
			 * @date 2022-09-21
			 */
			chooseLocation() {
				uni.chooseLocation({
					success: (res) => {
						console.log('chooseLocationSuccess', res)

						/* 发送位置 
							attach携带数据 name--位置名称 address--详细地址 latitude--纬度  longitude--经度 */
						this.sendMessage(4, {
							name: res.name,
							address: res.address,
							lat: res.latitude,
							lng: res.longitude
						})
					},
					fail: (res) => {
						console.log('chooseLocationFail', res)
					}
				})
			},

			//------------------------------ 以下为封装方法--------------------
			/**
			 * 结束录音数据重置
			 * 2022-08-12
			 */
			dataResetafterRecordStop() {
				// 更改语音提示文案
				this.voiceText = '按住 说话'

				// 清空计时器
				clearInterval(this.recordIntervalTimer)

				// 修改移动状态为未移动
				this.isTouchMove = false
				// 修改移动起始和结束Y轴距离为0
				this.touchStartY = 0
				this.touchEndY = 0
			},

			/**
			 * 发送信息
			 * @param {int} messageType 1--文本 2--语音 3--图片
			 * @date 2022-08-10
			 */
			sendMessage(messageType, attach = {}) {
				switch (messageType) {
					// 发送文本消息
					case 1:
						// 去除2边空格之后没有消息
						if (this.content.trim().length < 1) {
							this.cn.alert('不能发送空白消息')
							return false
							// 消息字数过多
						} else if (this.content.length > 2000) {
							this.cn.alert('发送字数要求在2000字以内')
							return false
						}

						let content = this.content

						// 发送成功之后清空文本框
						this.content = ''

						// 向外触发事件
						this.$emit('sendMessage', {
							message_type: 1,
							content: content
						})
						break;
						// 发送语音消息
					case 2:
						let recordSeconds = this.recordSeconds
						console.log(recordSeconds)
						let voiceUrl = this.voiceUrl

						// 发送成功之后清空数据
						this.voiceUrl = ''
						this.recordSeconds = 0

						// 向外触发事件
						this.$emit('sendMessage', {
							message_type: 2,
							content: voiceUrl,
							attach: {
								recordSeconds: recordSeconds
							}
						})
						break;
						// 发送图片消息
					case 3:
						let imageUrl = this.imageUrl

						// 发送成功之后清空数据
						this.imageUrl = ''

						// 向外触发事件
						this.$emit('sendMessage', {
							message_type: 3,
							content: imageUrl
						})
						break;
					case 4:
						// 向外触发事件
						this.$emit('sendMessage', {
							message_type: 4,
							content: attach.name,
							attach: {
								name: attach.name,
								address: attach.address,
								lat: attach.lat,
								lng: attach.lng
							}
						})
						break;
					default:
						break;
				}
			},

		}
	}
</script>

<style scoped>
	/* 底部栏 */
	.bottom-bar {
		position: fixed;
		left: 0;
		padding-bottom: env(safe-area-inset-bottom);
		z-index: 998;
		width: 100%;
		box-sizing: border-box;
	}


	/* 录音中状态，显示浮层 */
	.voice-record1 {
		position: fixed;
		top: calc(50vh - 140rpx);
		left: calc(50vw - 140rpx);
		height: 280rpx;
		width: 280rpx;
	}

	.voice-record {
		position: fixed;
		top: calc(50vh - 140rpx);
		left: calc(50vw - 140rpx);
		height: 280rpx;
		width: 280rpx;
		background: rgba(0, 0, 0, .5);
		border-radius: 10rpx;
	}

	.other-type-item {
		display: flex;
		flex-direction: column;
		align-items: center;
	}

	.other-type-item .icon-block {
		display: block;
		width: 110rpx;
		height: 110rpx;
		border-radius: 10rpx;
		background: #fff;
		text-align: center;
	}
</style>
