<template>
	<view class="main_div max_page no-touch">
		<nav-bar :is_seat="true"></nav-bar>
		<view class="nav-div">
			<view class="title ellipsis-text">
				{{ paperData.name }}
			</view>
			<view class="back_div" @click="exit_practice">
				<image :src="practiceExitIcon()" class="img"></image>
				<view class="text">退出</view>
			</view>
		</view>
		<view class="countdown-and-question-number-div">
			<view class="top">
				<view class="countdown">
					<text class="grey mr-10">当前题目/总题数</text>
					<text class="bold">{{ questionNumber + 1 }}</text>
					<text class="grey">/{{ storageTopicList.length }}</text>
				</view>
				<view class="question">
					<view class="grey">练习时长</view>
					<view class="countdown_time">
						{{ formatSeconds(practiceTime) }}
					</view>
				</view>
			</view>

			<view class="progress">
				<uv-line-progress
					:percentage="progress"
					:showText="false"
					activeColor="#FFFFFF"
					inactiveColor="#89B8FF"
					:height="8"
				></uv-line-progress>
			</view>
		</view>
		<view class="scroll_div">
			<swiper
				:disable-touch="showSwiper"
				ref="swiperRef"
				class="swiper"
				:indicator-dots="false"
				@change="swiperChange"
				:current="questionNumber"
				easing-function="linear"
				@transition="transition"
				@animationfinish="animationfinish"
			>
				<swiper-item v-for="(item, index) in topicList">
					<view class="content">
						<view class="expose_shadow"></view>
						<scroll-view :scroll-y="true" class="scroll-Y" :show-scrollbar="false" :refresher-threshold="0">
							<Subject
								:item="item"
								:mode="mode"
								:isPreview="item.isPreview"
								:clearResult="item.clearResult"
								@subject_click="subject_click"
								v-model="item.my_answer"
							></Subject>
						</scroll-view>
					</view>
				</swiper-item>
			</swiper>
		</view>

		<view class="fixed-box font_pf" :style="{ marginBottom: popup_input_bottom }">
			<view class="touch-btn-div" :class="{ show: showTouchBtn }">
				<TouchBtnOnlyVoice
					v-if="answerMethod === '03'"
					class="talk-btns"
					ref="touchBtnRef"
					@uploadVoice="touchBtnSubmit('voice', $event)"
					@submitAnswer="touchBtnSubmit('text', $event)"
					:isLoading="touchIsDisabled"
					loadingText="只能进行一条回答"
					:adjustPosition="false"
					:isDisabled="false"
					:onlyVoice="true"
					:answerMethod="answerMethod"
				/>
				<TouchBtn
					v-else
					class="talk-btns"
					ref="touchBtnRef"
					@uploadVoice="touchBtnSubmit('voice', $event)"
					@submitAnswer="touchBtnSubmit('text', $event)"
					:isLoading="touchIsDisabled"
					loadingText="只能进行一条回答"
					:adjustPosition="false"
					:isDisabled="false"
					:answerMethod="answerMethod"
					
				/>
				
			</view>
		</view>
		<!-- 反馈组件 -->
		<Feedback ref="feedbackRef"></Feedback>
		<!-- 结尾弹出层 -->
		<Dialog ref="dialogRef" @button_click="result_click"></Dialog>
	</view>
</template>

<script setup>
	import { ref, reactive, computed, onMounted, nextTick, onUnmounted } from 'vue';
	import { onLoad, onHide, onShow, onUnload, onBackPress, onReady } from '@dcloudio/uni-app';

	import Feedback from '@/pages/examination/components/feedback.vue';
	import Dialog from '@/pages/examination/components/dialog.vue';
	import Subject from '@/components/examination/subject.vue';
	import CharactersSubject from '@/components/examination/characters-subject.vue';
	// import TouchBtn from '@/components/examination/touchBtn.vue';
	import TouchBtn from '@/pages/course/components/touchBtn.vue';
	import TouchBtnOnlyVoice from '@/pages/course/components/touchBtnOnlyVoice.vue';
	import common from '@/common/common';
	import { setPageCache, formatSeconds, getPageCache, setupKeyboardHeightListener } from '@/common/common';
	import { commonUploadVoiceFile } from '@/api/common.js';
	import { optionErrorIcon, examinationSheetIcon, practiceExitIcon } from '@/common/imgSvg';
	import { practiceAnswer, practiceCommit, queryCrsPracticeAnswerResult } from '@/api/practice.js';
	import { startExamByCrs } from '@/api/examination.js';
	import { startPracticeByCrs } from '@/api/practice.js';
	const swiperRef = ref(null);
	const feedbackRef = ref(null);
	const dialogRef = ref(null);
	const touchBtnRef = ref(null);
	const answerMethod = ref('01');
	const practiceTime = ref(0); // 当前练习时间
	let practiceStartTime = 0; // 练习开始时间
	let practiceTimeTimer = null; // 练习计时器
	let leaveDuration = 0; // 当前总计离开时间
	let leaveStartTime = 0; // 离开开始时间
	const mode = ref('practice'); // 考试 examination 练习practice
	const systemInfo = uni.getSystemInfoSync();

	const paperData = reactive({
		exrId: '',
		crsId: '',
		name: '' // 名称
	}); // 试卷信息
	const topicList = reactive([]); // 问题列表
	const storageTopicList = ref([]); // 所有题列表
	const popup_input_bottom = ref('0px');
	const questionNumber = ref(0); // 题号

	const topic = computed({
		get: () => topicList[questionNumber.value],
		set: (val) => (topicList[questionNumber.value] = val)
	});

	const showTouchBtn = computed(() => {
		return topic.value?.qnsTyp === 'ES' && !topic.value?.my_answer.anserResult;
	});

	// 下面语音组件的禁用状态判断
	const touchIsDisabled = computed(() => {
		return topic.value?.es_status !== '' && topic.value?.es_status !== undefined;
	});

	const progress = computed(() => {
		// 计算进度百分比（保留两位小数）
		const total = storageTopicList.value.length;
		if (total === 0) return 0;
		const completed = questionNumber.value + 1;
		return Math.min(Math.round((completed / total) * 10000) / 100, 100);
	});

	// 滑动切换
	const swiperChange = (item) => {
		questionNumber.value = item.detail.current;
	};
	const isTriggered = ref(false); // 下面这个得防抖
	// 滑动发生改变
	const finishCurrent = ref(questionNumber.value);
	// 滑动组件结束事件
	const animationfinish = (event) => {
		finishCurrent.value = event.detail.current;
	};
	// 判断是否滑动结束
	const isLastTopic = computed(
		() => topicList.length === finishCurrent.value + 1 && finishCurrent.value === questionNumber.value
	);
	const showSwiper = ref(false);
	const transition = (event) => {
		if (isTriggered.value) return;
		const dx = event.detail.dx;
		if (dx > 80 && dx < 250 && isLastTopic.value && ['P', 'U'].includes(topic.value.judgeResult)) {
			// 如果是最后一题并且右滑动大于50,并且这题已经答了，就触发练习完成
			isTriggered.value = true;
			hand_in_paper_button_click();
		}
	};

	const subject_click = (type, params) => {
		if (type === 'feedback') {
			// 反馈
			feedbackRef.value.open(params.qnsId);
		} else if (type === 'answer') {
			//多选点击按钮答题
			if (params.qnsTyp === 'MU') {
				submitProblem({
					anserResult: params.answer.join(',')
				});
			}
		} else if (type === 'choose') {
			//单选判断点击选项答题
			if (['JD', 'SN'].includes(params.qnsTyp)) {
				submitProblem({ anserResult: params.answer.join(',') });
			}
		} else if (type === 'complete') {
			// 问答题点击完成
			submitProblem(params.answer);
		} else if (type === 'again') {
			// 问答题点击重答
			topic.value.my_answer = {};
			topic.value.isPreview = false;
			topic.value.es_status = ''; // 取消转圈
		}
	};

	// 单题回答
	const submitProblem = (answer) => {
		common.loading('答题中');
		practiceAnswer({
			exrId: paperData.exrId,
			ossKey: '',
			qnsId: topic.value.qnsId,
			showOrder: questionNumber.value + 1,
			examLenTm: practiceTime.value, // 练习时长
			...answer
		})
			.then(async (res) => {
				let traQnsInfoVo;
				// 是问答题
				if (topic.value.qnsTyp === 'ES') {
					try {
						const result = await queryWithRetry(res.body.execLogId);
						traQnsInfoVo = result.body.traQnsInfoVo;
					} catch (e) {
						common.hideLoading();
						topic.value.isPreview = false;
						return;
					}
				} else {
					traQnsInfoVo = res.body.traQnsInfoVo;
				}
				topic.value.isPreview = true; // 不能在点击了，打开预览模式
				console.log('给出来的traQnsInfoVo', traQnsInfoVo);
				common.hideLoading();
				topic.value.clearResult = false; // 不清除正确答案
				topic.value.analyContent = traQnsInfoVo.analyContent; // 答案解析
				// 更新选项正确项目
				topic.value.itemVos = traQnsInfoVo.itemVos; // 答案选项（todo应该不这样替换）
				topic.value.anserResult = traQnsInfoVo.anserResult; // 正确答案字符串分割
				topic.value.judgeResult = traQnsInfoVo.judgeResult; // 正确答案字符串分割
				const judgeResultStatus = traQnsInfoVo.judgeResult === 'P'; // P为正确U为错误
				if (!addProblem()) {
					// 返回false说明到了最后一题
					console.log('最后一题', topic.value.qnsTyp, !judgeResultStatus);
					if (topic.value.qnsTyp === 'ES' || !judgeResultStatus) {
						// 最后一题是问答题，或者答错了，都不自动弹出
						return;
					} else {
						hand_in_paper_button_click();
						return;
					}
				} else {
					// 自动切换下一题的条件
					if (
						judgeResultStatus && // 条件1.答题正确
						topic.value.qnsTyp !== 'ES' // 问答题答对打答错都不切换
					) {
						nextTick(() => {
							setTimeout(() => {
								questionNumber.value++;
							}, 200);
						});
					}
				}
			})
			.catch(() => {
				// 单选和判断需要清除已点击的按钮
				if (['JD', 'SN'].includes(topic.value.qnsTyp)) {
					topic.value.my_answer = [];
				}
				common.hideLoading();
			});
	};

	// 问答题轮询结果方法
	const queryWithRetry = (execLogId, maxRetries = 10) => {
		// 递归终止条件：达到最大重试次数
		if (maxRetries <= 0) {
			return Promise.reject(new Error('超过最大重试次数，查询失败'));
		}
		return queryCrsPracticeAnswerResult({ execLogId })
			.then((res) => {
				console.log('queryCrsPracticeAnswerResult', maxRetries, res.body);
				const isWait = res.body.isWait;
				if (isWait === 'Y') {
					// 如果是Y，延迟2秒后重试，重试次数减1
					return new Promise((resolve) => {
						setTimeout(() => {
							resolve(queryWithRetry(execLogId, maxRetries - 1));
						}, 2000);
					});
				} else {
					// 不是Y，直接返回结果
					return res;
				}
			})
			.catch((error) => {
				// 对接口调用错误进行重试
				if (maxRetries > 0) {
					return new Promise((resolve) => {
						setTimeout(() => {
							resolve(queryWithRetry(execLogId, maxRetries - 1));
						}, 2000);
					});
				}
				return Promise.reject(error);
			});
	};

	// 录音组件提交
	const touchBtnSubmit = (type, submitObj) => {
		const topic = topicList[questionNumber.value];
		touchBtnRef.value?.clearInputText(); // 清除发送框数据
		if (type === 'voice') {
			if (topic.es_status === '00') return;
			topic.es_status = '00'; // 00转圈
			const voicePath = submitObj;
			commonUploadVoiceFile(voicePath, '/traask/traAskchat/voiceTrans', {})
				.then((_res) => {
					const _content = _res.body.transContent.trim();
					if (_content === '') {
						topic.es_status = ''; // 取消转圈
						return common.msg('未识别到文字');
					} else {
						topic.es_status = '02';
						topic.my_answer = {
							anserResult: _res.body.transContent,
							ossKey: _res.body.fileId,
							ossAddr: _res.body.ossFileAddr,
							voicePath: voicePath
						};
					}
				})
				.catch((error) => {
					topic.es_status = ''; // 取消转圈
					if (error === 'Other') {
						common.msg('系统异常，请联系管理员');
					}
				});
		} else if (type === 'text') {
			topic.es_status = '01';
			topic.my_answer = {
				anserResult: submitObj // 正确答案文字内容
			};
		}
	};

	// 添加一道题
	const addProblem = () => {
		if (topicList.length >= storageTopicList.value.length) {
			return false;
		}
		topicList.push(storageTopicList.value[topicList.length]);
		return true;
	};
	const examStat = ref('');
	// 初始化时检查
	onLoad((e) => {
		examStat.value = e.examStat ?? '';
		const practice = getPageCache('practice');
		if (!practice) {
			common.navigateBack();
			return;
		}
		paperData.crsId = practice.crsId;
		paperData.name = practice.name;
		paperData.exrId = practice.exrId;
		answerMethod.value = practice.answerMethod ?? '01';
		storageTopicList.value = practice.qnsInfoVos.map((res) => ({
			...res,
			isPreview: false,
			clearResult: true,
			es_status: '', // 预设一下问答题的状态，'' 空为没有 00 转圈 01 播放，其他暂定
			my_answer: [],
			answerMethod: answerMethod.value
		}));
		addProblem();
		// 记录练习起始时间
		practiceStartTime = new Date().getTime();
		setupKeyboardHeightListener((height) => {
			popup_input_bottom.value = `${height}px`;
			console.log('需要卸载吗');
		});
	});
	const result_click = async ({ key }) => {
		isTriggered.value = false; // 恢复
		if (key === 'exit') {
			// 中途退出
			dialogRef.value.close();
			common.loading();
			try {
				await practiceCommit({ exrId: paperData.exrId, examLenTm: practiceTime.value, stat: 'U' });
			} catch (e) {}
			common.navigateBack();
			common.hideLoading();
		} else if (key === 'revert') {
			// 返回
			dialogRef.value.close();
		}
	};
	const style_button_1 = {
		color: '#FFFFFF',
		fontSize: '30rpx',
		backgroundColor: '#0066FF',
		borderRadius: '8rpx'
	};
	const style_button_2 = {
		color: '#0066FF',
		fontSize: '30rpx',
		backgroundColor: '#E2EDFF',
		borderRadius: '8rpx'
	};
	// 弹出框配置
	const dialogConfiguration = reactive({});
	// 交卷按钮点击，打开交卷确认框
	const hand_in_paper_button_click = () => {
		console.log('交卷按钮');
		const stat = 'P';
		showSwiper.value = true;
		// 2. 延迟 50ms 确保 swiper 已销毁，再跳转

		nextTick(() => {
			common.redirectTo(
				`/pages/practice/result?name=${paperData.name}&exrId=${paperData.exrId}&crsId=${paperData.crsId}&examLenTm=${practiceTime.value}&stat=${stat}&examStat=${examStat.value}`
			);
		});
	};
	// 中途退出
	const exit_practice = () => {
		dialogRef.value.open({
			title: '确认现在退出吗？',
			buttonList: [
				{
					key: 'exit',
					name: '退出',
					style: style_button_1
				},
				{
					key: 'revert',
					name: '返回',
					style: style_button_2
				}
			]
		});
	};
	// 启动练习时长定时器
	const startTimer = () => {
		if (practiceTimeTimer) {
			clearInterval(practiceTimeTimer);
		}
		practiceTimeTimer = setInterval(() => {
			const currentTime = Date.now();
			const elapsedSeconds = Math.floor((currentTime - practiceStartTime - leaveDuration) / 1000);
			practiceTime.value = elapsedSeconds;
		}, 1000);
	};
	// 暂停定时器
	const stopTimer = () => {
		if (practiceTimeTimer) {
			clearInterval(practiceTimeTimer);
			practiceTimeTimer = null;
		}
	};
	onShow(() => {
		if (leaveStartTime) {
			const time = Date.now() - leaveStartTime;
			leaveDuration += time;
			leaveStartTime = 0; // 重置离开开始时间
		}
		startTimer(); // 启动/恢复定时器
	});
	onHide(() => {
		leaveStartTime = new Date().getTime();
		stopTimer();
	});
	onUnload(() => {
		stopTimer();
	});

	onBackPress((res) => {
		if (res.from === 'backbutton') {
			exit_practice();
			return true;
		}
	});
</script>

<style scoped lang="scss">
	$bg-margin-left: 30rpx;
	.popup_title_text {
		color: red;
	}

	.popup {
		//答题卡
		z-index: 1800;
		padding: 0 38rpx;

		.sheet_popup_div {
			width: 100%;
			height: 100%;
			background-color: #ffffff;
			padding: 10rpx 34rpx;
			display: flex;
			flex-direction: column;
			align-items: center;
			border-radius: 16rpx 16rpx 0px 0px;
			position: relative;

			.title_div {
				width: 100%;
				text-align: center;
				padding: 30rpx 0;
				font-family: PingFangSC;
				font-weight: 600;
				font-size: 34rpx;
				color: #000000;
				text-align: center;
				font-style: normal;
				border-bottom: 2rpx solid #efefef;
			}

			.popup_back_div {
				width: 60rpx;
				height: 60rpx;
				position: absolute;
				top: 30rpx;
				right: 30rpx;
				display: flex;
				align-items: center;
				justify-content: center;

				.img {
					width: 30rpx;
					height: 30rpx;
				}
			}

			.sheet_table {
				margin-top: 48rpx;
				margin-bottom: 48rpx;
				display: flex;
				flex-wrap: wrap;
				width: calc(100vw - 108rpx);
				align-content: space-between;

				.sheet_table_item {
					width: calc((100vw - 108rpx) / 5 - 16rpx);
					height: calc((100vw - 108rpx) / 5 - 16rpx);
					margin: 8rpx;
					border: 2rpx solid #e5e5e5;
					border-radius: 50%;
					display: flex;
					align-items: center;
					justify-content: center;
					font-size: 32rpx;
					color: #999999;
				}

				.current {
					background-color: rgba(0, 102, 255, 0.6);
					border-color: #0066ff;
					color: #ffffff;
				}

				.completed {
					// 已完成
					background-color: rgba(0, 102, 255, 0.1);
					border-color: #0066ff;
					color: #0066ff;
				}

				.mark,
				.completed.mark {
					background-color: rgba(232, 181, 49, 0.1);
					color: #e8b531;
					border-color: #e8b531;
				}

				.current.mark {
					// 已完成
					background-color: rgba(0, 102, 255, 0.6);
					color: #ffffff;
					border-color: #e8b531;
				}
			}

			.sheet_button {
				width: 100%;
			}
		}
	}

	.fixed-box {
		position: fixed;
		width: 100%;
		left: 0;
		bottom: 0;
		border-radius: 16rpx 16rpx 0px 0px;
		border: 2rpx solid #e5e5e5;
		background: #ffffff;
	}

	.touch-btn-div {
		height: 0;
		overflow: hidden;
		transition: height 0.2s ease-out;
	}

	.touch-btn-div.show {
		height: 150rpx;
	}

	.fixed-btn-box {
		height: 154rpx;
		display: flex;
		justify-content: space-between;
		align-items: center;
		padding: 0 20rpx 20rpx 20rpx;

		.sheet_button {
			display: flex;
			flex-direction: column;
			align-items: center;
			margin: 0 70rpx;

			.img {
				width: 38rpx;
				height: 40rpx;
			}

			.sheet_text {
				margin-top: 8rpx;
				font-family: PingFangSC;
				font-weight: 500;
				font-size: 24rpx;
				color: #000000;
			}
		}

		.button_div {
			flex: 1;

			display: flex;
			justify-content: space-between;

			.button {
				flex: 1;
			}
		}
	}

	.scroll-Y {
		max-height: calc(100vh - var(--status-bar-height) - 70rpx - 70rpx - 40rpx - 64rpx - 68rpx - 60rpx);
		min-height: calc(100vh - var(--status-bar-height) - 70rpx - 70rpx - 40rpx - 64rpx - 68rpx - 60rpx - 380rpx);
	}

	.swiper {
		// 状态栏 var(--status-bar-height)
		// 标题栏 70rpx
		// 进度时间栏 70rpx
		// 进度时间栏上下间距 40rpx = 20rpx + 20rpx
		// 正文上下间距 64rpx
		height: calc(100vh - var(--status-bar-height) - 70rpx - 70rpx - 40rpx - 64rpx);
		// background-color: red;
	}

	.content {
		position: relative;
		margin: 32rpx $bg-margin-left;
		border-radius: 16rpx;
		padding: 34rpx 30rpx 34rpx 36rpx;
		background-color: #fff;

		.expose_shadow {
			margin-left: 36rpx;
			position: absolute;
			bottom: -26rpx;
			left: 0%;
			width: calc(100% - 66rpx);
			height: 28rpx;
			background-color: #ffffff;
			border-radius: 0 0 14rpx 14rpx;
			opacity: 0.4;
			z-index: 0;
			// background-color: red;
		}
	}

	.countdown-and-question-number-div {
		margin: 20rpx $bg-margin-left;
		height: 70rpx;
		// background-color: red;
		display: flex;
		flex-direction: column;
		justify-content: space-between;
		z-index: 10;

		.top {
			display: flex;
			align-items: center;
			justify-content: space-between;
			font-family: PingFangSC;
			font-size: 26rpx;
			color: #ffffff;
			text-align: left;
			font-style: normal;
		}

		.question {
			display: flex;
			align-items: center;
			width: 242rpx;
			flex-wrap: nowrap;

			.grey {
				margin-right: 8rpx;
			}

			.countdown_time {
				white-space: nowrap;
			}

			color: #ffffff;
			font-weight: 600;
			font-size: 26rpx;
		}

		.grey {
			color: #b6e2ff;
			white-space: nowrap;
		}

		.bold {
			font-weight: 600;
		}
	}

	.nav-div {
		position: relative;
		.title {
			margin: 0 calc($bg-margin-left + 90rpx);
			height: 70rpx;
			font-family: PingFangSC;
			font-weight: 500;
			font-size: 34rpx;
			color: #ffffff;
			text-align: center;
			font-style: normal;
			line-height: 70rpx;
		}

		.back_div {
			position: absolute;
			right: $bg-margin-left;
			top: 0;
			height: 70rpx;
			display: flex;
			align-items: center;
			justify-content: flex-end;
			.img {
				width: 32rpx;
				height: 32rpx;
			}
			.text {
				color: #eaeaea;
				font-size: 24rpx;
				white-space: nowrap;
				margin-left: 4rpx;
			}
		}
	}

	.main_div {
		display: flex;
		flex-direction: column;
		background: linear-gradient(to top, #3480ff, #0066ff);
		/* 确保背景占满整个视口高度 */
		// min-height: 100vh;
		margin: 0;
	}
</style>
