<template>
	<view>
		<scroll-view class="scroll-view" scroll-y scroll-with-animation :scroll-top="top">
			<view style="padding: 30rpx 30rpx 240rpx;">
				<view class="message" :class="[item.userType]" v-for="(item, index) in list" :key="index"
					@click="msgClick(item, index)">
					<image :src="item.avatar" v-if="item.userType === 'friend'" class="avatar" mode="widthFix"></image>
					<view class="content" v-if="item.messageType === 'image'">
						<image :src="item.content" mode="widthFix"></image>
					</view>

					<!-- 加载状态消息 -->
					<view class="content loading-content" v-else-if="item.isLoading">
						<view class="loading-dots">
							<view class="dot" v-for="i in 3" :key="i"></view>
						</view>
					</view>
					<view class="content voice-content" v-else-if="item.messageType === 'voice'">
						<a-trumpet :isPlay="item.isplay" style="margin-right: 4rpx;"></a-trumpet>
						{{ item.content }}
					</view>
					<view class="content" v-else>
						{{ item.content }}
					</view>
					<image :src="item.avatar" v-if="item.userType === 'self'" class="avatar" mode="widthFix"></image>
				</view>


			</view>
		</scroll-view>

		<view class="tool">
			<block v-if="messageType === 'text'">
				<image src="../../static/voice.png" mode="widthFix" class="left-icon" @click="messageType = 'voice'">
				</image>
				<input type="text" v-model="content" class="input" @confirm="send" />
				<image src="../../static/thumb.png" mode="widthFix" class="thumb" @click="send"></image>
			</block>
			<block v-else-if="messageType === 'voice'">
				<image src="../../static/text.png" mode="widthFix" class="left-icon" @click="messageType = 'text'">
				</image>
				<text class="voice-crl" @touchstart="touchstart" @touchend="touchend">{{ recordStart ? '松开 发送' : '按住 说话'
					}}</text>
			</block>
		</view>

		<view v-if="recordStart" class="audio-animation">
			<view class="audio-wave">
				<text class="audio-wave-text" v-for="item in 10" :style="{ 'animation-delay': `${item / 10}s` }"></text>
				<view class="text">松开 发送</view>
			</view>

		</view>



	</view>
</template>

<script>
const innerAudioContext = uni.createInnerAudioContext();
const plugin = requirePlugin("WechatSI")
const manager = plugin.getRecordRecognitionManager()

import permision from '../../common/permission.js';

import {
	getAIReply,
	getChatLog
} from '@/services/api.js';

export default {
	data() {
		return {
			person_id: '',
			permisionState: false,
			content: '',
			list: [],
			top: 0,
			messageType: 'voice', // text 发送文本；voice 发送语音
			recordStart: false,
			isLoading: false, // 添加loading状态变量
			playingIndex: -1,
		};
	},
	onShow() {
		// uni.hideHomeButton()
	},
	onLoad(options) {

		this.person_id = uni.getStorageSync('person_id');


		uni.setNavigationBarTitle({
			title: '芽芽星语'
		})
		this._friendAvatar = 'https://ww1.sinaimg.cn/mw690/a1a9fb72gy1hl1cd1znplj20j60j6n0h.jpg'
		this._selfAvatar = 'https://ask.dcloud.net.cn/uploads/avatar/001/43/07/62_avatar_max.jpg?=1705916918'


		getChatLog({
			page: '1',
			page_size: '10',
			person_id: this.person_id
		}).then((res) => {
			const messages = [];
			res.data.data.forEach(item => {
				// 添加用户消息
				messages.push({
					content: item.user_input,
					userType: 'self',
					avatar: this._selfAvatar
				});

				// 添加AI回复消息
				messages.push({
					content: `${Math.ceil(item.duration)}''`,
					audioSrc: item.audio_url,
					userType: 'friend',
					avatar: this._friendAvatar,
					messageType: 'voice',
					isplay: false // 明确设置初始值
				});

				// 使用数组赋值而不是push，确保响应式更新
				this.list = messages;

			});
		}).catch((err) => {
			console.log(err)
		}).finally(() => {
			this.scrollToBottom();
		})


		// this.list = [{
		// 		content: '历史消息',
		// 		userType: 'friend',
		// 		messageType: 'voice',
		// 		avatar: this._friendAvatar
		// 	},
		// 	{
		// 		content: '历史消息',
		// 		userType: 'self',
		// 		avatar: this._selfAvatar
		// 	}
		// ]

		manager.onStart = () => {
			console.log('==onStart==')
			this.recordStart = true
		};

		manager.onStop = (res) => {
			console.log('==onStop==', res)
			this.recordStart = false
			this.voicePath = res.tempFilePath;
			this.voiceText = res.result;
			if (this.voiceText == '') {
				this.voiceText = '周围太安静啦~再试试~';
			}

			// 创建新的消息数组
			const newList = [...this.list];

			// 添加用户消息
			newList.push({
				content: this.voiceText,
				userType: 'self',
				avatar: this._selfAvatar
			});

			// 添加loading消息
			const loadingIndex = newList.length;
			newList.push({
				content: 'loading',
				userType: 'friend',
				avatar: this._friendAvatar,
				isLoading: true,
				isplay: false
			});

			// 更新整个列表
			this.list = newList;
			this.scrollToBottom();

			// this.list.push({
			// 	content: this.voiceText,
			// 	userType: 'self',
			// 	avatar: this._selfAvatar
			// })

			// this.scrollToBottom();

			// // 先添加一个loading状态的消息
			// this.isLoading = true;
			// this.list.push({
			// 	content: 'loading',
			// 	userType: 'friend',
			// 	avatar: this._friendAvatar,
			// 	isLoading: true,
			// 	isplay: false
			// })
			// this.loadingMessageIndex = this.list.length - 1;
			// this.scrollToBottom();

			getAIReply({
				prompt: this.voiceText,
				person_id: this.person_id
			}).then((res) => {
				// 再次创建新数组以更新loading消息
				const updatedList = [...this.list];
				updatedList[loadingIndex] = {
					content: `${Math.ceil(res.data.duration)}''`,
					audioSrc: res.data.url,
					userType: 'friend',
					avatar: this._friendAvatar,
					messageType: 'voice',
					isplay: false
				};
				this.list = updatedList;

				innerAudioContext.src = res.data.url;
				innerAudioContext.play();

				// 监听播放结束事件
				innerAudioContext.onEnded(() => {
					this.$set(this.list[loadingIndex], 'isplay', false);
				});

				// 监听错误事件
				innerAudioContext.onError(() => {
					this.$set(this.list[loadingIndex], 'isplay', false);
				});
			}).catch((err) => {
				// 错误处理：将loading消息更新为错误提示
				this.list[this.loadingMessageIndex] = {
					content: '抱歉，获取回复失败，请重试',
					userType: 'friend',
					avatar: this._friendAvatar,
					isLoading: false
				};
			}).finally(() => {
				this.isLoading = false;
				this.scrollToBottom();
			})
		};
		// 识别错误事件  
		manager.onError = (err) => {
			uni.showToast({
				title: '错误(' + err.retcode + ')：' + err.msg,
				icon: 'none',
				duration: 2000, //持续时间为 2秒
			})
		};
	},
	onHide() {
		if (this._innerAudioContext) {
			this._innerAudioContext.stop()
		}
	},
	created() {
		this.checkPermission();
	},
	methods: {

		upx2px(upx) {
			return uni.upx2px(upx) + 'px';
		},
		send() {

			if (this.content.length == 0) {
				return;
			}

			const _content = this.content;

			// 创建新的消息数组
			const newList = [...this.list];

			// 添加用户消息
			newList.push({
				content: this.content,
				userType: 'self',
				avatar: this._selfAvatar
			});

			// 添加loading消息
			const loadingIndex = newList.length;
			newList.push({
				content: 'loading',
				userType: 'friend',
				avatar: this._friendAvatar,
				isLoading: true,
				isplay: false
			});

			// 更新整个列表
			this.list = newList;
			this.scrollToBottom();
			this.content = '';


			getAIReply({
				prompt: _content,
				person_id: this.person_id
			}).then((res) => {
				// 再次创建新数组以更新loading消息
				const updatedList = [...this.list];
				updatedList[loadingIndex] = {
					content: `${Math.ceil(res.data.duration)}''`,
					audioSrc: res.data.url,
					userType: 'friend',
					avatar: this._friendAvatar,
					messageType: 'voice',
					isplay: true
				};
				this.list = updatedList;

				innerAudioContext.src = res.data.url;
				innerAudioContext.play();

				// 监听播放结束事件
				innerAudioContext.onEnded(() => {
					this.$set(this.list[loadingIndex], 'isplay', false);
				});

				// 监听错误事件
				innerAudioContext.onError(() => {
					this.$set(this.list[loadingIndex], 'isplay', false);
				});
			}).catch((err) => {
				console.log(err)
				// 错误处理：将loading消息更新为错误提示
				this.list[this.loadingMessageIndex] = {
					content: '抱歉，获取回复失败，请重试',
					userType: 'friend',
					avatar: this._friendAvatar,
					isLoading: false
				};
			}).finally(() => {
				this.isLoading = false;
				this.scrollToBottom();
			})
		},

		scrollToBottom() {
			this.top = this.list.length * 1000
		},

		msgClick(data, index) {
			if (data.messageType === 'voice') {
				// 先停止之前可能在播放的音频
				innerAudioContext.stop();

				// 重置所有消息的播放状态
				this.list.forEach((msg, i) => {
					if (msg.messageType === 'voice') {
						this.$set(this.list[i], 'isplay', false);
					}
				});

				// 设置当前消息的播放状态
				this.$set(this.list[index], 'isplay', true);

				// 播放音频
				innerAudioContext.src = data.audioSrc;
				innerAudioContext.play();

				// 监听播放结束事件
				innerAudioContext.onEnded(() => {
					this.$set(this.list[index], 'isplay', false);
				});

				// 监听错误事件
				innerAudioContext.onError(() => {
					this.$set(this.list[index], 'isplay', false);
				});
			}
		},

		authTips() {
			uni.showModal({
				title: '提示',
				content: '您拒绝了麦克风权限，将导致功能不能正常使用，去设置权限？',
				confirmText: '去设置',
				cancelText: '取消',
				success: (res) => {
					if (res.confirm) {
						uni.openSetting({
							success: (res) => {
								if (res.authSetting['scope.record']) {
									console.log("已授权麦克风");
									this._recordAuth = true
								} else {
									// 未授权
									wx.showModal({
										title: '提示',
										content: '您未授权麦克风，功能将无法使用',
										showCancel: false,
										confirmText: '知道了'
									})
								}
							}
						})
					}
				}
			})
		},

		touchstart() {
			if (!this.permisionState) {
				this.checkPermission();
				return;
			}
			manager.start({
				duration: 60000,
				lang: "zh_CN"
			})

		},

		async checkPermission() {
			var that = this;
			// #ifdef APP-PLUS
			// 先判断os
			let os = uni.getSystemInfoSync().osName;
			if (os == 'ios') {
				this.permisionState = await permision.judgeIosPermission('record');
			} else {
				this.permisionState = await permision.requestAndroidPermission('android.permission.RECORD_AUDIO');
			}
			if (this.permisionState !== true && this.permisionState !== 1) {
				uni.showToast({
					title: '请先授权使用录音',
					icon: 'none'
				});
				return;
			}
			// #endif			

			// #ifdef MP-WEIXIN
			uni.authorize({
				scope: 'scope.record',
				success(e) {
					that.permisionState = true;
				},
				fail() {
					uni.showToast({
						title: '请授权使用录音',
						icon: 'none'
					});
				}
			});
			// #endif
		},

		touchend() {
			if (!this.recordStart) return
			manager.stop();
		},

		//播放声音
		play(src) {
			this._innerAudioContext = wx.createInnerAudioContext()
			this._innerAudioContext.src = src
			this._innerAudioContext.play()
			this._innerAudioContext.onPlay(() => {
				console.log('开始播放')
			})
			this._innerAudioContext.onEnded(() => {
				// 播放完毕，清除音频链接
				console.log('播放完毕');
			})
			this._innerAudioContext.onError((res) => {
				console.log('audio play error', res)
			})
		},
	}
}
</script>

<style lang="scss" scoped>
.scroll-view {
	/* #ifdef H5 */
	height: calc(100vh - 44px);
	/* #endif */
	/* #ifndef H5 */
	height: 100vh;
	/* #endif */
	background: #eee;
	box-sizing: border-box;
}

.message {
	display: flex;
	align-items: flex-start;
	margin-bottom: 30rpx;

	.avatar {
		width: 80rpx;
		height: 80rpx;
		border-radius: 10rpx;
		margin-right: 30rpx;
	}

	.content {
		min-height: 86rpx;
		max-width: 60vw;
		box-sizing: border-box;
		font-size: 28rpx;
		line-height: 1.3;
		padding: 20rpx;
		border-radius: 10rpx;
		background: #fff;
		display: flex;
		align-items: center;

		image {
			width: 200rpx;
		}
	}

	.voice-content {
		display: flex;
		align-items: center;
		width: 24vw;
	}

	&.self {
		justify-content: flex-end;

		.avatar {
			margin: 0 0 0 30rpx;
		}

		.content {
			position: relative;

			&::after {
				position: absolute;
				content: '';
				width: 0;
				height: 0;
				border: 16rpx solid transparent;
				border-left: 16rpx solid #fff;
				right: -28rpx;
				top: 24rpx;
			}
		}
	}

	&.friend {
		.content {
			position: relative;

			&::after {
				position: absolute;
				content: '';
				width: 0;
				height: 0;
				border: 16rpx solid transparent;
				border-right: 16rpx solid #fff;
				left: -28rpx;
				top: 24rpx;
			}
		}
	}
}

.tool {
	position: fixed;
	width: 100%;
	min-height: 120rpx;
	left: 0;
	bottom: 0;
	background: #fff;
	display: flex;
	align-items: center;
	box-sizing: border-box;
	padding: 20rpx 24rpx 20rpx 40rpx;
	padding-bottom: calc(20rpx + constant(safe-area-inset-bottom)/2) !important;
	padding-bottom: calc(20rpx + env(safe-area-inset-bottom)/2) !important;

	.left-icon {
		width: 56rpx;
		height: 56rpx;
		margin-right: 10rpx;
	}

	.input,
	.voice-crl {
		background: #eee;
		border-radius: 10rpx;
		height: 70rpx;
		margin-left: 10rpx;
		margin-right: 20rpx;
		flex: 1;
		padding: 0 20rpx;
		box-sizing: border-box;
		font-size: 28rpx;
	}

	.thumb {
		width: 64rpx;
		height: 64rpx;
	}

	.voice-crl {
		text-align: center;
		line-height: 70rpx;
		font-weight: bold;
	}
}

.audio-animation {
	position: fixed;
	// width: 100vw;
	// height: 100vh;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%);
	z-index: 202410;
	display: flex;
	justify-content: center;
	align-items: center;

	.text {
		text-align: center;
		font-size: 28rpx;
		color: #333;
		margin-top: 60rpx;
	}

	.audio-wave {
		padding: 50rpx;

		.audio-wave-text {
			background-color: blue;
			width: 7rpx;
			height: 12rpx;
			margin: 0 6rpx;
			border-radius: 5rpx;
			display: inline-block;
			border: none;
			animation: wave 0.25s ease-in-out;
			animation-iteration-count: infinite;
			animation-direction: alternate;
		}

		/*  声波动画  */
		@keyframes wave {
			from {
				transform: scaleY(1);
			}

			to {
				transform: scaleY(4);
			}
		}
	}
}

.loading-content {
	min-width: 100rpx;
	display: flex;
	justify-content: center;
	align-items: center;
}

.loading-dots {
	display: flex;
	align-items: center;
}

.dot {
	width: 12rpx;
	height: 12rpx;
	background-color: #999;
	border-radius: 50%;
	margin: 0 6rpx;
	animation: dot-animation 1.4s infinite ease-in-out both;
}

.dot:nth-child(1) {
	animation-delay: -0.32s;
}

.dot:nth-child(2) {
	animation-delay: -0.16s;
}

@keyframes dot-animation {

	0%,
	80%,
	100% {
		transform: scale(0);
	}

	40% {
		transform: scale(1);
	}
}
</style>