<template>
	<view>
		<view class="dock">
			<view style="display: flex;">
				<scroll-view class="quick-actions horizontal" scroll-x show-scrollbar="false"
					style="width: calc(100% - 50px);">
					<!-- <view class="qa-btn minor" @tap="onSwitchModel">切换模型</view> -->
					<view class="qa-btn" @tap="onQuickAsk(item.quickAskText)" v-for="item in quickAskList"
						:key="item.quickAskText" @longpress.prevent="deleteQucikAsk(item)">
						{{ item.quickAskText }}
					</view>
				</scroll-view>
				<view class="quick-add" @tap="inputDialogToggle">
					<image style="width: 40px;" src="@/static/plus-circle-fill.png" mode="widthFix"></image>
				</view>
			</view>
			<view class="input-bar">
				<input class="input" confirm-type="send" v-model="inputTextValue" @confirm="onSend()"
					placeholder="你可以说…" placeholder-class="ph" />
				<view :class="['mic', { recording: isRecording }]" @touchstart.stop="onPressMic"
					@touchmove.stop="onMoveMic" @touchend.stop="onReleaseMic">🎙️</view>
				<!-- <button class="send" type="primary" @tap="onSend">发送</button> -->
				<view
					:class="['send', (!isReplying && inputTextValue && inputTextValue.trim()) ? 'normal' : 'disabled']">
					<image v-if="isReplying" src="@/static/break.png" mode="widthFix" style="width: 20px;"
						@tap="handleBreak"></image>
					<image v-else src="@/static/top-arrows.png" mode="widthFix" style="width: 20px;" @tap="onSend">
					</image>
				</view>
			</view>
		</view>
		<view v-if="isRecording" class="record-mask">
			<view class="record-box" :class="{ cancel: willCancel }">
				<view class="record-icon">🎙️</view>
				<view class="record-text">{{
		  willCancel ? "松开手指，取消发送" : "手指上滑，取消发送"
		}}</view>
			</view>
		</view>

		<uni-popup ref="inputDialog" type="dialog" style="z-index: 10003;" >
			<uni-popup-dialog ref="inputClose" mode="input" title="添加快捷提问" v-model="dialogText" placeholder="请输入内容"
				@confirm="dialogInputConfirm" :maxlength="15" @close='dialogInputClose'></uni-popup-dialog>
		</uni-popup>

		<view v-if="isRecording" class="mask-layer"> </view>
	</view>
</template>

<script>
	import {
		recognizeAudio
	} from "@/utils/uploadVoice.js";
	export default {
		props: {
			inputText: {
				type: String,
				default: ''
			},
			isReplying: {
				type: Boolean,
				default: false
			}
		},
		data() {
			return {
				quickAskList: [
					{
						quickAskText : '设备运行情况'
					},
					{
						quickAskText : '今日出入库数据'
					}
				],
				searchHeight: 0,
				inputTextValue: '',
				isRecording: false,
				willCancel: false,
				recorder: null,
				recordStartY: 0,
				recordStartTs: 0,
				recordSimTimer: null,
				dialogText: ''
			}
		},
		mounted() {
			let self = this;
			uni.createSelectorQuery().select(".dock").boundingClientRect((rect) => {
				self.searchHeight = Math.ceil(rect.height)
			}).exec();
		},
		beforeDestroy() {
			if (this.recordSimTimer) {
				clearTimeout(this.recordSimTimer);
			}
		},
		watch: {
			inputText(newValue) {
				this.inputTextValue = newValue;
			},
			inputTextValue(newValue) {
				this.$emit('changeInputText', newValue)
			}
		},
		methods: {
			deleteQucikAsk(item){
				uni.showModal({
					title: "提示",
					content: "确定要删除这条快捷提问？",
					success : res => {
						if(res.confirm){
							this.quickAskList = this.quickAskList.filter(ele => ele.quickAskText !== item.quickAskText);
							uni.showToast({
								title: '删除成功',
								icon: 'none'
							})
						}
					}
				})
			},
			dialogInputClose(){
				this.$emit('changeShow',false)
			},
			inputDialogToggle() {
				this.dialogText = '';
				this.$refs.inputDialog.open();
				this.$emit('changeShow',true)
			},
			dialogInputConfirm() {
				this.$emit('changeShow',false)
				if(!this.dialogText && !this.dialogText.trim()){
					uni.showToast({
						title: '内容不能为空',
						icon: 'none'
					})
					return;
				}
				let index = this.quickAskList.findIndex(item => item.quickAskText.trim() === this.dialogText.trim());
				if(index > -1){
					uni.showToast({
						title: '不能重复添加内容',
						icon: 'none'
					})
					return;
				}
				this.quickAskList.unshift({
					quickAskText : this.dialogText,				
				});
			},
			handleBreak() {
				this.$emit('handleBreak')
			},
			getHeight() {
				return this.searchHeight
			},
			onSwitchModel() {
				uni.showToast({
					title: "已切换为通用模型",
					icon: "none",
				});
			},
			// 快速提问
			onQuickAsk(text) {
				this.$emit('onQuickAsk', text);
			},
			onSend() {
				if (this.isReplying) return;
				this.$emit('onSend')
				// 清空输入框并同步父组件
				this.inputTextValue = ''
				this.$emit('changeInputText', '')
			},
			ensureRecorder() {
				if (this.recorder) return;
				try {
					this.recorder = uni.getRecorderManager && uni.getRecorderManager();
				} catch (e) {
					this.recorder = null;
				}
				if (this.recorder) {
					this.recorder.onStart();
					this.recorder.onStop(async (res) => {
						this.$emit('changeShow',false)
						const duration = Date.now() - this.recordStartTs;
						if (this.willCancel || duration < 700) {
							uni.showToast({
								title: duration < 700 ? "说话时间太短" : "已取消",
								icon: "none",
							});
							return;
						}
						uni.showLoading({
							title: "识别中...",
							mask: true
						});
						const text = await recognizeAudio(res.tempFilePath);
						if (!text?.trim()) {
							uni.showToast({
								title: '未识别到文字',
								icon: 'none'
							})
							return;
						}
						this.$emit('changeInputText', text)
						uni.hideLoading();
						// TODO: 上传 res.tempFilePath 做识别；现用 mock
						// this.handleRecognizedText(this.mockSpeechToText(duration), res.tempFilePath, Math.ceil(
						// 	duration / 100) / 10)
						this.onSend();
					});
				}
			},
			onPressMic(e) {
				if (process.env.UNI_PLATFORM !== 'APP-PLUS' && process.env.UNI_PLATFORM !== 'app-plus') {
					uni.showToast({
						title: '当前模式暂时只在APP支持',
						icon: 'none'
					})
					return;
				}
				if (this.isLoading)
					return uni.showToast({
						title: "AI正在回复中",
						icon: "none",
					});
				const appAuthorizeSetting = uni.getAppAuthorizeSetting();
				if (appAuthorizeSetting.microphoneAuthorized !== 'authorized') {
					uni.showModal({
						title: '权限设置',
						content: '应用缺乏必要的权限，是否前往手动授予该权限？',
						complete: res => {
							if (res.confirm) {
								uni.openAppAuthorizeSetting()
							}
						}
					})
					return
				}
				this.$emit('changeShow',true)
				this.ensureRecorder();
				this.isRecording = true;
				this.willCancel = false;
				this.recordStartTs = Date.now();
				this.recordStartY =
					e.changedTouches && e.changedTouches[0] ?
					e.changedTouches[0].clientY :
					0;
				if (this.recorder) {
					try {
						this.recorder.start({
							format: "amr",
							sampleRate: 16000,
							numberOfChannels: 1,
							duration: 60000,
						});
					} catch (err) {}
				} else {
					if (this.recordSimTimer) clearTimeout(this.recordSimTimer);
					this.recordSimTimer = setTimeout(() => {}, 60000);
				}
			},
			// 录音时移动
			onMoveMic(e) {
				if (!this.isRecording) return;
				const y =
					e.changedTouches && e.changedTouches[0] ?
					e.changedTouches[0].clientY :
					0;
				this.willCancel = this.recordStartY - y > 60;
			},
			// 松开录音
			onReleaseMic() {
				console.log('onReleaseMic');
				if (!this.isRecording) return;
				this.isRecording = false;
				this.show = false;
				if (this.recorder) {
					try {
						this.recorder.stop();
					} catch (err) {
						console.log("err", err);
					}
				}
			}
		}
	}
</script>

<style scoped>
	.dock {
		position: fixed;
		left: 0;
		right: 0;
		bottom: 0;
		background: #f7f8fc;
		box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.06);
		padding-bottom: constant(safe-area-inset-bottom);
		padding-bottom: env(safe-area-inset-bottom);
		z-index: 999;
	}

	.quick-actions {
		padding: 6px 10px 4px;
	}

	.quick-actions.horizontal {
		white-space: nowrap;
		width: 100%;
		padding-right: 10px;
		box-sizing: border-box;
	}

	.quick-add {
		display: flex;
		align-items: center;
		justify-content: center;
	}

	.qa-btn {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		min-width: 96px;
		text-align: center;
		background: #fff;
		border-radius: 10px;
		padding: 8px 10px;
		font-size: 12px;
		color: #3b3f45;
		box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
		margin-right: 10px;
	}

	.qa-btn.minor {
		background: #eff1ff;
		color: #4e7bff;
	}

	.qa-btn:last-child {
		margin-right: 0;
	}

	.input-bar {
		display: flex;
		align-items: center;
		padding: 8px 10px 12px;
		gap: 8px;
		background: #f7f8fc;
	}

	.input {
		flex: 1;
		background: #fff;
		border-radius: 24px;
		padding: 10px 14px;
		font-size: 14px;
	}

	.ph {
		color: #9aa3b2;
	}

	.mic {
		width: 36px;
		height: 36px;
		border-radius: 18px;
		background: #fff;
		display: flex;
		align-items: center;
		justify-content: center;
		box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
	}

	.mic.recording {
		background: #fffbf0;
		box-shadow: 0 0 0 2px rgba(255, 193, 7, 0.25) inset;
	}

	.send {
		height: 36px;
		width: 36px;
		border-radius: 50%;
		background: #4e7bff;
		display: flex;
		align-items: center;
		justify-content: center;
	}

	.disabled {
		background-color: #ddd;
	}

	.normal {
		background-color: #4e7bff;
	}

	.record-mask {
		position: fixed;
		left: 0;
		right: 0;
		top: 0;
		bottom: 0;
		display: flex;
		align-items: center;
		justify-content: center;
		z-index: 9999;
	}

	.record-box {
		background: rgba(0, 0, 0, 0.75);
		color: #fff;
		padding: 16px 18px;
		border-radius: 12px;
		display: flex;
		align-items: center;
		gap: 10px;
		min-width: 220rpx;
	}

	.record-text {
		font-size: 14px;
	}

	.mask-layer {
		position: fixed;
		left: 0;
		right: 0;
		top: 0;
		bottom: 0;
		background-color: rgba(0, 0, 0, 0.1);
		z-index: 100004;
	}

	.cancel {
		color: red;
	}
</style>