<template>
	<view class="pages">
		<digital-human :width="0" rootStyle="position: fixed; left: 50%; top: 100px; transform: translateX(-50%);">
		</digital-human>

		<image class="bgs" src="https://qufang.oss-cn-beijing.aliyuncs.com/serverBg.jpg" mode="" />

		<view class="server-box">
			<view class="server-head">
				<image class="servehead" src="@/static/image/servehead.png" mode="" />
				<image class="voiceing" src="@/static/image/voiceing.png" mode="" />
			</view>

			<!-- 消息列表 -->
			<scroll-view class="scroll-box" scroll-y :scroll-into-view="scrollId">
				<!-- 循环体 -->
				<block v-for="(item, index) in messageList">
					<!-- 左侧 -->
					<view :class="item.direction" :key="index" :id="`scrollId${index}`">
						<view class="msg-text">
							<view class="msg-texts">
								{{ item.text }}
							</view>
							<image @tap="rePlayText(item.text)" v-if="item.direction == 'lside' && index !== 0 "
								class="voiceplay" src="@/static/image/voiceplay.png" mode="" />
						</view>
						<view class="timer">{{ item.time }}</view>
					</view>
				</block>
			</scroll-view>
			<view class="send-box">

				<view v-if="sendType" class="input-box">
					<input v-model="inputText" class="inputs" placeholder-class="placestyle" type="text"
						confirm-type="send" @confirm="sendChat" placeholder="输入你想咨询的问题或点击右边的麦克风和我聊天" />
				</view>

				<view v-else class="voice-box" @touchstart="touchStart" @touchend="touchEnd">
					<text>{{ voiceState }}</text>
				</view>

				<view class="change-type">
					<image @tap="changeSendType(false)" v-if="sendType" src="@/static/image/voiceInput.png" mode="" />
					<image @tap="changeSendType(true)" v-else src="@/static/image/textInput.png" mode="" />
				</view>
			</view>
		</view>


		<view v-if="recording" class="luyin">
			<image src="@/static/image/recordingIcon.png" mode="" />
			<text>正在录音...</text>
		</view>

	</view>
</template>

<script>
	const pluginConfig = { // 数字人配置
	    "asrConfig": {
	      "class": "TencentASR",
	      "secretKey": "",
	      "secretId": "AKIDyvwuvrfikhYK1dDj9Vlv154zmVAjFdt0",
	      "appId": 1310500600,
	      "partnerId": "0002",
	      "signatureUrl": "https://commercial-integration-asr-int-api.xiaoice.com/api/v3/asr/tencentSignature",
	      "hotWordId": "2ab7be50d11f11ecbfd6525400aec391",
	      "silenceTime": 240,
	      "engineModelType": "16k_zh",
	      "needVad": 1,
	      "filterDirty": 1,
	      "filterModal": 0,
	      "filterPunc": 1,
	      "vadSilenceTime": 240,
	      "convertNumMode": 1,
	      "wordInfo": 2
	    },
	    "character": "chenzheling-yellow",
	    "characterConfig": {
	      "characters": {
	        "chenzheling-yellow": {
	          "name": "chenzheling-yellow-half",
	          "id": "chenzheling-yellow",
	          "frameWidth": 740,
	          "frameHeight": 1260,
	          "faceWidth": 190,
	          "faceHeight": 300,
	          "facePositionLeft": 450,
	          "facePositionTop": 550,
	          "facePositionLeftOffset": -180,
	          "facePositionTopOffset": -430,
	          "frameRate": 25,
	          "defaultIdle": "A-idle",
	          "idles": {
	            "A-idle": {
	              "id": "A-idle",
	              "version": 6,
	              "frameImageLength": 227,
	              "frameImageType": "webp",
	              "resetFrameSingleNum": 8,
	              "resetFrames": [7, 15, 23, 31, 39, 47, 55, 63, 71, 79, 87, 95, 103, 111, 119, 127, 135, 143, 151, 159, 167, 175, 183, 191, 199, 207, 215, 223],
	              "frameImageBackupType": "png"
	            }
	          },
	          "gestures": {},
	          "crops": {}
	        }
	      },
	      "sourcePath": "https://commercial-cdn.xiaoice.com/assets/images/characters",
	      "batch": 16,
	      "minLoadFrameNum": 100
	    },
	    "chatConfig": {
	      "class": "CXHubChat",
	      "url": "https://commercial-fab.xiaoice.com/api/hub/organizations/org-qufangwang/agents/64af7b6d6e1ba4813c4bd6ae/environments/draft/sessions",
	      "defaultReply": [{
	        "text": "对不起，我没听清~",
	        "gesture": ""
	      }],
	      "csChatUrl": "https://commercial-fab.xiaoice.com/api/hub/organizations/org-qufangwang/characters//sessions"
	    },
	    "logConfig": {
	      "class": "AliTraceLogger",
	      "metaData": {
	        "role": "prod",
	        "organizationId": "org-qufangwang",
	        "partnerId": "dh-api",
	        "agentId": "64af7b6d6e1ba4813c4bd6ae"
	      }
	    },
	    "talkConfig": {
	      "class": "CarouselTalk",
	      "url": "https://commercial-fab.xiaoice.com",
	      "options": {
	        "path": "/api/v1/carousel/avatars/chenzheling-yellow/socket.io",
	        "wsPath": "/api/v1/carousel/avatars/chenzheling-yellow/websocket",
	        "transports": ["websocket", "polling"],
	        "query": "?image_format=.webp&voice_id=64af7b6da9d616bd022f6b69"
	      },
	      "maxRetryTime": 5,
	      "retryTimeInterval": 100
	  }
	}
	const plugin = requirePlugin('digital-human-plugin').api; // 数字人实例
	const plugins = requirePlugin("WechatSI");
	let manager = plugins.getRecordRecognitionManager();


	export default {
		data() {
			return {
				sendType: true, // true 为文字输入 false 为语音输入
				messageList: [], // 消息列表
				inputText: '', // 文字输入
				voiceState: '按住 说话', // 
				recording: false, // 展示录音提示框
				scrollId: '', // 默认不滚动
			};
		},

		onLoad() {
			uni.showLoading({
				title: '加载中...',
			})
			plugin.init({
				...pluginConfig,
				onReceivedAsrText: (text) => {},
				onSuccess: (res) => {
					console.log(res, 'onSuccess')
					uni.hideLoading()
					let text = 'Hi～我是专业房产顾问嘉欣，有问题可以问我呦，试试说句“你好”和我打个招呼吧'
					plugin.human?.talkAsync(text)
					this.messageList.push({
						text: text,
						direction: 'lside'
					})
				},
				onFailed: res => {
					uni.hideLoading()
					console.log(res, 'onFailed')
				},
				onError: (res) => {
					uni.hideLoading()
					console.log(res, 'onError')
				}
			})

			this.initRecord()
		},

		onShow() {
			// #ifdef MP-WEIXIN

			// 内存告警处理
			wx.onMemoryWarning((level) => {
				plugin.clearCache()
			})
			wx.setInnerAudioOption({
				// IOS静音键的情况下允许播放声音
				obeyMuteSwitch: false,
				// 播放声音时中断其他app端声音
				mixWithOther: false,
			})
			// #endif
		},
		onHide() {},
		methods: {
			/**
			 * 切换输入方式
			 */
			changeSendType(e) {
				this.sendType = e
			},

			// // 模拟聊天回复接口
			async getReply(text) {
				console.log(this.setUid())
				await uni.request({
					url: `${pluginConfig.chatConfig.url}/${this.setUid()}`,
					method: 'POST',
					data: {
						"text": text,
						"currentSceneInfo": {
							"sceneId": ""
						}
					},
					success: async (res) => {
						const replay = res.data.sceneInfo[0].audioText[0]
						await plugin.human?.interrupt()
						let arr = []
						arr.push({
							direction: 'rside',
							text: text,
							time: this.getTimeNow()
						})
						arr.push({
							direction: 'lside',
							text: res.data.sceneInfo[0].audioText[0],
							time: this.getTimeNow()
						})
						this.messageList = [...this.messageList, ...arr]
						this.inputText = ''
						this.scrollId = `scrollId${this.messageList.length-1}`

						await plugin.human?.talkAsync(replay)
					}
				})
			},



			/**
			 * 重播当前对话
			 */
			async rePlayText(e) {
				console.log(e)
				// 暂停当前对话（如果有）
				await plugin.human?.interrupt()
				await plugin.human?.talkAsync(e)
			},


			/**
			 * 获取当前时间
			 */
			getTimeNow() {
				let now = new Date();
				let year = now.getFullYear(); //获取完整的年份(4位,1970-????)
				let month = now.getMonth() + 1; //获取当前月份(0-11,0代表1月)
				let today = now.getDate(); //获取当前日(1-31)
				let hour = now.getHours(); //获取当前小时数(0-23)
				let minute = now.getMinutes(); //获取当前分钟数(0-59)
				let second = now.getSeconds(); //获取当前秒数(0-59)
				let nowTime = ''
				nowTime = year + '-' + this.fillZero(month) + '-' + this.fillZero(today) + ' ' + this.fillZero(hour) +
					':' +
					this.fillZero(minute) + ':' + this.fillZero(second)
				return nowTime
			},
			// 补零
			fillZero(str) {
				var realNum;
				if (str < 10) {
					realNum = '0' + str;
				} else {
					realNum = str;
				}
				return realNum;
			},


			/**
			 * 发送文字
			 */
			async sendChat(e) {
				await this.getReply(e.detail.value)
			},

			/**
			 * 长按识别
			 */
			touchStart() {
				this.recording = true
				manager.start({
					duration: 60000,
					lang: "zh_CN"
				});
			},

			/**
			 * 长按结束
			 * */
			touchEnd() {
				this.recording = false
				manager.stop();
			},
			/**  
			 * 初始化语音识别回调  
			 * 绑定语音播放开始事件  
			 */
			initRecord() {
				manager.onStart = (res) => {
					this.voiceState = "正在录音"
				};
				//有新的识别内容返回，则会调用此事件  
				manager.onRecognize = (res) => {}

				// 识别结束事件  
				manager.onStop = async (res) => {

					if (res.result) {
						await this.getReply(res.result)
					}

					this.voiceState = "按住 说话"
				}

				// 识别错误事件  
				manager.onError = (res) => {}
			},

			// 简单生成uid
			setUid() {
				let uid = new Date().getTime() + Math.random().toString(36).substr(2);
				return uid
			},


		}
	};
</script>
<style lang="scss" scoped>
	/* pages/intelligentvoiceassistant/intelligentvoiceassistant.wxss */
	view {
		box-sizing: border-box;
	}

	.pages {
		position: relative;
		width: 100vw;
		height: 100vh;
		display: flex;
		flex-direction: column;
		justify-content: flex-end;
	}

	.bgs {
		position: absolute;
		z-index: 0;
		width: 100%;
		height: 100%;
	}

	.server-box {
		position: relative;
		z-index: 10;
		width: calc(100%-1rpx);
		height: 658rpx;
		background: rgba(0, 0, 0, 0.5);
		backdrop-filter: saturate(180%) blur(20px);
		border-radius: 32rpx 32rpx 0 0;
		border: 1rpx solid #FFFFFF;
	}

	.server-head {
		margin: -130rpx 0 0 0;
		padding: 0 32rpx;
		width: 100%;
		display: flex;
		align-items: flex-end;
	}

	.servehead {
		width: 192rpx;
		height: 192rpx;
	}

	.voiceing {
		margin-left: 12rpx;
		width: 78rpx;
		height: 50rpx;
	}

	/* 
.close {
  width: ;
} */


	.scroll-box {
		width: 100%;
		height: calc(658rpx - 192rpx + 130rpx - 104rpx);
	}

	.lside {
		display: flex;
		flex-direction: column;
		align-items: flex-start;
	}

	.rside {
		display: flex;
		flex-direction: column;
		align-items: flex-end;
	}

	.msg-texts {
		margin: 36rpx 32rpx 12rpx;
		padding: 16rpx 28rpx;
		background: #fff;
		border-radius: 20rpx;
	}

	.lside .voiceplay {
		margin: 0 32rpx 16rpx 16rpx;
	}

	.lside .msg-text {
		display: flex;
		align-items: flex-end;
	}

	.lside .msg-text .msg-texts {
		margin: 36rpx 16rpx 12rpx 32rpx;
	}


	.timer {
		margin: 0 32rpx;
		font-size: 24rpx;
		font-family: PingFangSC-Regular, PingFang SC;
		font-weight: 400;
		color: #FFFFFF;
		line-height: 33rpx;
	}

	.rside .msg-texts {
		background: #2671E2;
		color: #fff;
	}

	.send-box {
		padding: 0 24rpx;
		width: 100%;
		height: 104rpx;
		background: #5D6168;
		display: flex;
		align-items: center;
		/* justify-content: center; */
	}

	.change-type {
		margin: 0 0 0 24rpx;
		width: 72rpx;
		height: 72rpx;
	}

	.change-type image {
		width: 72rpx;
		height: 72rpx;
	}

	.input-box,
	.voice-box {
		width: 606rpx;
		height: 72rpx;
		background: #FFFFFF;
		border-radius: 12rpx;
	}

	.voice-box {
		display: flex;
		justify-content: center;
		align-items: center;
	}

	.voice-box text {
		font-size: 28rpx;
		font-family: PingFangSC-Medium, PingFang SC;
		font-weight: 500;
		color: #000000;
		line-height: 40rpx;
	}

	.inputs {
		padding: 0 28rpx;
		box-sizing: border-box;
		width: 100%;
		height: 100%;
		font-size: 22rpx;
		font-family: PingFangSC-Regular, PingFang SC;
		font-weight: 400;
		line-height: 30rpx;
	}

	.placestyle {
		font-size: 22rpx;
		font-family: PingFangSC-Regular, PingFang SC;
		font-weight: 400;
		color: #CCCCCC;
		line-height: 30rpx;
	}


	.luyin {
		position: fixed;
		left: 50%;
		top: 50%;
		transform: translate(-50%, -50%);
		z-index: 100;
		width: 280rpx;
		height: 258rpx;
		background: rgba(0, 0, 0, 0.7);
		border-radius: 20rpx;
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
	}

	.luyin image {
		margin: 0 0 20rpx 0;
		width: 46rpx;
		height: 62rpx;
	}

	.luyin text {
		font-size: 28rpx;
		font-family: PingFangSC-Regular, PingFang SC;
		font-weight: 400;
		color: #FFFFFF;
		line-height: 40rpx;
	}

	.voiceplay {
		flex-shrink: 0;
		width: 64rpx;
		height: 64rpx;
	}
</style>
