<template>
	<s-layout class="chat-wrap" title="语音转文字">
		<view class="chat-container">
			<view class="messages" :style="{height:messagesHeight+'px'}" id="messages">
				<view v-for="(message, index) in messages" :key="index" class="message" @click="playRecording(index)">
					<view class="bubble">
						<text class="duration">{{ message.duration }}" </text><text class="ss-m-l-10">
							<image src="@/static/icon/audioPaly.png" class="audioPaly" />
						</text>
					</view>
					<view class="text" v-if="message.transcription != null && message.transcription != ''">
						{{message.transcription}}
					</view>
				</view>
			</view>
			<view class="input-area">
				<button @mousedown="startRecording" @mouseup="stopRecording" @mouseleave="cancelRecording"
					@touchstart="startRecording" @touchend="stopRecording" @touchcancel="cancelRecording"
					@touchmove="handleTouchMove">
					按住 说话
				</button>
				<view v-if="isRecording" class="recording-overlay">
					<view>{{ recordingDuration }}</view>
					<view>上滑至此取消</view>
				</view>
			</view>
		</view>
	</s-layout>
</template>

<script setup>
	import {
		ref,
		nextTick,
		onMounted
	} from 'vue';
	import sheep from '@/sheep';
	import VoiceApi from '@/sheep/api/system/voice';
	const {
		safeAreaInsets,
		safeArea
	} = sheep.$platform.device;
	const sysNavBar = sheep.$platform.navbar;
	const messagesHeight = (safeArea.height) - sysNavBar - 20 - 60;

	const messages = ref([]);
	const isRecording = ref(false);
	let startTime = ref(null);
	const recordingDuration = ref('');
	const minRecordingTime = 500; // 设置最小录音时间为500毫秒
	let intervalId = null;
	const cancelOffset = 280; // 上滑取消的距离阈值
	const startTouchY = ref(0);
	let mediaRecorder = null;
	let audioChunks = [];
	let isCancelled = ref(false);

	// 初始化录音功能
	onMounted(() => {
		navigator.mediaDevices.getUserMedia({
				audio: true
			})
			.then(stream => {
				mediaRecorder = new MediaRecorder(stream);
				mediaRecorder.ondataavailable = (event) => {
					audioChunks.push(event.data);
				};
				mediaRecorder.onstop = () => {
					if (!isCancelled.value) {
						sendDuration()
					}
					audioChunks = [];
				};
			})
			.catch(error => {
				console.error("Error accessing media devices.", error);
			});
	});
	async function sendAudioToServer(audioBlob,audioUrl,duration,messageIndex) {
	  const formData = new FormData();
	  formData.append('audio_file', audioBlob);
	  try {
	    const response = await fetch(import.meta.env.SHOPRO_BASE_URL + '/voice2text/', {
	      method: 'POST',
	      body: formData,
	    });
	    const data = await response.json();
		if(data.success){
			messages.value[messageIndex].transcription = data.transcription;
		}
	    console.log('Server response:', data);
	  } catch (error) {
	    console.error('Error sending audio file:', error);
	  }
	}
	// 发送录音
	const sendDuration = () => {
		const audioBlob = new Blob(audioChunks, {
			type: 'audio/mpeg'
		});
		const audioUrl = URL.createObjectURL(audioBlob);
		const duration = Math.max(Math.floor((new Date() - startTime.value) / 1000), 1);
		  // 先添加消息,但不包含转写文本
		const messageIndex = messages.value.push({
		    duration,
		    audioUrl,
		    transcription: '' // 初始为空
		}) - 1;
		sendAudioToServer(audioBlob,audioUrl,duration,messageIndex);
		nextTick(() => {
			let messagesElement = document.getElementById('messages');
			messagesElement.scrollTop = messagesElement.scrollHeight;
		});
	}

	// 更新录音
	const updateDuration = () => {
		const currentDuration = Math.floor((new Date() - startTime.value) / 1000);
		recordingDuration.value = currentDuration + 's';
		if (currentDuration >= 60) { // 如果到达60秒自动停止录音
			stopRecording(new Event('mouseup'));
		}
	};
	// 开始录音
	const startRecording = (event) => {
		if (!isRecording.value && (event.type === 'mousedown' || event.type === 'touchstart')) {
			startTime.value = new Date();
			isRecording.value = true;
			intervalId = setInterval(updateDuration, 1000); // 每秒更新一次时间
			recordingDuration.value = '1s'; // 开始时显示1秒
			// console.log('开始录音...');
			event.preventDefault();
			startTouchY.value = event.touches ? event.touches[0].clientY : 0;
			audioChunks = [];
			isCancelled.value = false; // 确保开始录音时取消标志为假
			mediaRecorder.start();
		}
	};
	// 停止录音
	const stopRecording = (event) => {
		if (isRecording.value && (event.type === 'mouseup' || event.type === 'touchend' || event.type ===
				'mouseleave' || event.type === 'touchcancel')) {
			clearInterval(intervalId); // 停止定时器
			isRecording.value = false;
			recordingDuration.value = ''; // 清空显示的时间

			if (new Date() - startTime.value >= minRecordingTime) {
				mediaRecorder.stop();
			} else {
				console.log('录音时间太短,不保存');
			}

		}
	};
	// 取消录音
	const cancelRecording = () => {
		if (isRecording.value) {
			clearInterval(intervalId);
			console.log('录音取消');
			isCancelled.value = true; // 设置取消标志为真
			mediaRecorder.stop();
			resetRecording();
		}
	};
	// 重置录音
	const resetRecording = () => {
		isRecording.value = false;
		recordingDuration.value = 0;
		startTime.value = null;
		audioChunks = [];
	};
	// 处理触摸移动事件
	const handleTouchMove = (event) => {
		// 此处应添加逻辑来检测触摸位置,如果滑动到取消区域,调用 cancelRecording
		const currentTouchY = event.touches[0].clientY;
		if (startTouchY.value - currentTouchY > cancelOffset) { // 检查是否上滑超过阈值
			cancelRecording();
		}
	};
	// 播放录音
	const playRecording = (index) => {
		const message = messages.value[index];
		const audio = new Audio(message.audioUrl);
		audio.play();
	};
</script>

<style scoped>
	.chat-container {
		display: flex;
		flex-direction: column;
		overflow-y: auto;
		background-color: #f0f0f0;
		padding: 10px;
	}

	.messages {
		flex-grow: 1;
		overflow-y: auto;
	}

	.message {
		display: flex;
		justify-content: flex-end;
		align-items: flex-end;
		margin-bottom: 10px;
		flex-direction: column;
	}
	.text{
		width: 70%;
		background: white;
		border-radius: 5px;
		padding: 10px;
		margin: 5px 0 10px;
		box-sizing: border-box;
		font-size: 16px;
	}
	.bubble {
		width:100px;
		padding: 10px 20px 10px 20px;
		justify-content: flex-end;
		margin-right: 10px;
		background-color: rgb(131 235 96);
		border-radius: 5px;
		display: flex;
		align-items: right;
		position: relative;
	}

	.bubble::after {
		content: "";
		width: 0px;
		height: 0px;
		border-top: 5px solid transparent;
		border-bottom: 5px solid transparent;
		border-left: 5px solid #83eb60;
		position: absolute;
		top: 14px;
		right: -5px;
	}

	.duration {
		color: #000;
		font-size: 16px;
	}

	.audioPaly {
		width: 12px;
		height: 12px;
	}

	.input-area {
		position: fixed;
		bottom: 0;
		left: 0;
		width: 100%;
		background-color: rgb(245, 245, 245);
		display: flex;
		justify-content: center;
		padding: 10px;
		box-sizing: border-box;
	}

	.input-area>button {
		display: block;
		width: 100%;
		background-color: #FFFFFF;
		border: none;
		padding: 3px 0;
		border-radius: 5px;
		color: #333333;
		font-size: 16px;
		font-weight: bold;
		text-align: center;
		outline: none;
		cursor: pointer;

	}

	.input-area>.button-hover {
		background-color: #f0f0f0 !important;
	}

	.input-area>button:after {
		border: none;
	}

	.recording-overlay {
		position: fixed;
		top: 50%;
		left: 50%;
		transform: translate(-50%, -50%);
		background-color: rgba(0, 0, 0, 0.7);
		color: white;
		padding: 20px;
		border-radius: 10px;
		text-align: center;
	}

	.recording-overlay view {
		margin: 5px 0;
	}
</style>