import { Popup, Snackbar } from "@varlet/ui";
import { defineComponent, onMounted, reactive, watch } from "vue";
import {
	connectWebsocket,
	evaluatingData,
	handleEndBegin,
	handleEndSoundCheck,
	handlePerformDetection,
	handleStartBegin,
	handleStartEvaluat,
	handleViewReport,
} from "/src/view/evaluating";
import Earphone from "./earphone";
import styles from "./index.module.less";
import SoundEffect from "./sound-effect";
import state from "/src/state";
import { storeData } from "/src/store";
import { browser } from "/src/utils";
import { getNoteByMeasuresSlursStart } from "/src/helpers/formateMusic";
import { Icon, NoticeBar, showToast, Swipe, SwipeItem } from "vant";
import iconStudent from "./icons/student.png";
import EvaluatResult from "./evaluat-result";
import EvaluatAudio from "./evaluat-audio";
import { api_openWebView, api_proxyServiceMessage, api_videoUpdate } from "/src/helpers/communication";
import EvaluatShare from "./evaluat-share";

// frequency 频率, amplitude 振幅, decibels 分贝
type TCriteria = "frequency" | "amplitude" | "decibels";

export default defineComponent({
	name: "evaluat-model",
	setup() {
		const evaluatModel = reactive({
			tips: true,
			evaluatUpdateAudio: false,
			isSaveVideo: state.setting.camera && state.setting.saveToAlbum,
			shareMode: false,
		});
		/**
		 * 木管(长笛 萨克斯 单簧管)乐器一级的2、3、6测评要放原音音频
		 * 铜管乐器一级的1a，1b，5，6测评要放原音音频
		 */
		const getMusicMode = () => {
			const muguan = [2, 4, 5, 6];
			const tongguan = [12, 13, 14, 15, 17];
			if (muguan.includes(state.subjectId) && (state.examSongName || "").search(/[^\u0000-\u00FF](1-2|1-3|1-6)/gi) > -1) {
				return "music";
			}
			if (tongguan.includes(state.subjectId) && (state.examSongName || "").search(/[^\u0000-\u00FF](1-1-1|1-1-2|1-5|1-6)/gi) > -1) {
				return "music";
			}
			if ([23, 113, 121].includes(state.subjectId)) {
				return "music";
			}
			return "background";
		};
		const browserInfo = browser();
		/** 是否是节奏练习 */
		const isRhythmicExercises = () => {
			const examSongName = state.examSongName || "";
			return examSongName.indexOf("节奏练习") > -1;
		};

		/** 获取评测标准 */
		const getEvaluationCriteria = () => {
			let criteria: TCriteria = "frequency";
			// 声部打击乐
			if ([23, 113, 121].includes(state.subjectId)) {
				criteria = "amplitude";
			} else if (isRhythmicExercises()) {
				// 分类为节奏练习
				criteria = "decibels";
			}
			return criteria;
		};

		/** 生成评测曲谱数据 */
		const formatTimes = () => {
			let ListenMode = false;
			let dontEvaluatingMode = false;
			let skip = false;
			const datas = [];
			for (let index = 0; index < state.times.length; index++) {
				const item = state.times[index];
				const note = getNoteByMeasuresSlursStart(item);
				const rate = state.speed / state.originSpeed;
				const difftime = item.difftime;
				const start = difftime + (item.sourceRelativeTime || item.relativeTime);
				const end = difftime + (item.sourceRelaEndtime || item.relaEndtime);
				const isStaccato = note.noteElement.voiceEntry.isStaccato();
				const noteRate = isStaccato ? 0.5 : 1;
				if (note.formatLyricsEntries.contains("Play") || note.formatLyricsEntries.contains("Play...")) {
					ListenMode = false;
				}
				if (note.formatLyricsEntries.contains("Listen")) {
					ListenMode = true;
				}
				if (note.formatLyricsEntries.contains("纯律结束")) {
					dontEvaluatingMode = false;
				}
				if (note.formatLyricsEntries.contains("纯律")) {
					dontEvaluatingMode = true;
				}
				const nextNote = state.times[index + 1];
				// console.log("noteinfo", note.noteElement.isRestFlag && !!note.stave && !!nextNote)
				if (skip && (note.stave || !item.noteElement.isRestFlag || (nextNote && !nextNote.noteElement.isRestFlag))) {
					skip = false;
				}
				if (note.noteElement.isRestFlag && !!note.stave && !!nextNote && nextNote.noteElement.isRestFlag) {
					skip = true;
				}
				// console.log(note.measureOpenIndex, item.measureOpenIndex, note);
				// console.log("skip", skip)
				const data = {
					timeStamp: (start * 1000) / rate,
					duration: ((end * 1000) / rate - (start * 1000) / rate) * noteRate,
					frequency: item.frequency,
					nextFrequency: item.nextFrequency,
					prevFrequency: item.prevFrequency,
					// 重复的情况index会自然累加,render的index是谱面渲染的index
					measureIndex: note.measureOpenIndex,
					measureRenderIndex: item.measureListIndex,
					dontEvaluating: ListenMode || dontEvaluatingMode,
					musicalNotesIndex: item.i,
					denominator: note.noteElement?.Length.denominator,
				};
				datas.push(data);
			}
			return datas;
		};
		/** 连接websocket */
		const handleConnect = async () => {
			const behaviorId = localStorage.getItem("behaviorId") || undefined;
			const rate = state.speed / state.originSpeed;
			const content = {
				musicXmlInfos: formatTimes(),
				id: state.examSongId,
				subjectId: state.subjectId,
				detailId: state.detailId,
				examSongId: state.examSongId,
				xmlUrl: state.xmlUrl,
				partIndex: state.partIndex,
				behaviorId,
				tenantId: storeData.user.tenantId,
				platform: browserInfo.ios ? "IOS" : browserInfo.android ? "ANDROID" : "WEB",
				clientId: storeData.platformType === "STUDENT" ? "student" : storeData.platformType === "TEACHER" ? "teacher" : "education",
				speed: state.speed,
				heardLevel: state.setting.evaluationDifficulty,
				beatLength: Math.round((state.fixtime * 1000) / rate),
				campId: sessionStorage.getItem("campId") || "",
				evaluationCriteria: getEvaluationCriteria(),
			};
			const result = await connectWebsocket(content);
			state.playSource = getMusicMode();
		};

		/** 评测结果按钮处理 */
		const handleEvaluatResult = (type: "practise" | "tryagain" | "look" | "share" | "update") => {
			if (type === "update") {
				// 上传云端
				evaluatModel.evaluatUpdateAudio = true;
				return;
			} else if (type === "share") {
				// 分享
				evaluatModel.shareMode = true;
				return;
			} else if (type === "look") {
				// 跳转
				handleViewReport();
				return;
			} else if (type === "practise") {
				// 去练习
				handleStartEvaluat();
			} else if (type === "tryagain") {
				// 再来一次
				handleStartBegin();
			}
			evaluatingData.resulstMode = false;
		};
		/** 上传音视频 */
		const hanldeUpdateVideoAndAudio = async (update = false) => {
			if (!update) {
				evaluatModel.evaluatUpdateAudio = false;
				return;
			}
			let res = null;
			if (evaluatModel.isSaveVideo) {
				res = await api_videoUpdate();
			}
			api_proxyServiceMessage({
				header: {
					commond: "videoUpload",
					status: 200,
					type: "SOUND_COMPARE",
				},
				body: {
					filePath: res?.content?.filePath,
					recordId: res?.recordId,
				},
			});
			Snackbar.success("上传成功");
			evaluatModel.evaluatUpdateAudio = false;
		};

		onMounted(() => {
			handlePerformDetection();
		});
		watch(
			() => evaluatingData.checkEnd,
			() => {
				if (evaluatingData.checkEnd) {
					console.log("检测结束,连接websocket");
					handleConnect();
				}
			}
		);
		watch(
			() => evaluatingData.startBegin,
			() => {
				if (evaluatingData.startBegin) {
					evaluatModel.tips = false;
				}
			}
		);
		return () => (
			<div>
				{evaluatingData.websocketState && (
					<>
						{!evaluatingData.startBegin && (
							<div class={styles.btn} onClick={handleStartBegin}>
								开始演奏
							</div>
						)}
						{evaluatingData.startBegin && (
							<div class={[styles.btn, styles.endBtn]} onClick={() => handleEndBegin(false)}>
								<Icon name="success" />
								<span>结束演奏</span>
							</div>
						)}
					</>
				)}
				{evaluatModel.tips && (
					<>
						<div class={styles.notice}>
							<img src={iconStudent} />
							<NoticeBar
								scrollable={false}
								style="background: #fff;color: #01C1B5;"
								mode="closeable"
								onClose={() => {
									evaluatModel.tips = false;
								}}
							>
								<Swipe style="height: 32px;" show-indicators={false} autoplay={3000} vertical>
									<SwipeItem>请在周围安静的环境下演奏，减少杂音</SwipeItem>
									<SwipeItem>请选择稳定、良好的网络环境，避免信号中断</SwipeItem>
									<SwipeItem>演奏前请调试好乐器，保证最佳演奏状态</SwipeItem>
									<SwipeItem>演奏时请佩戴耳机，评测收音更精准</SwipeItem>
								</Swipe>
							</NoticeBar>
						</div>
						<div style={{ height: "40px" }}></div>
					</>
				)}
				<Popup teleport="body" closeOnClickOverlay={false} defaultStyle={false} v-model:show={evaluatingData.earphoneMode}>
					<Earphone
						onClose={() => {
							evaluatingData.earphoneMode = false;
							handlePerformDetection();
						}}
					/>
				</Popup>
				<Popup teleport="body" closeOnClickOverlay={false} defaultStyle={false} v-model:show={evaluatingData.soundEffectMode}>
					<SoundEffect
						onClose={(value: any) => {
							evaluatingData.soundEffectMode = false;
							if (value) {
								state.setting.soundEffect = false;
							}
							handleEndSoundCheck();
							handlePerformDetection();
						}}
					/>
				</Popup>

				<Popup teleport="body" closeOnClickOverlay={false} defaultStyle={false} v-model:show={evaluatingData.resulstMode}>
					<EvaluatResult onClose={handleEvaluatResult} />
				</Popup>
				<Popup teleport="body" closeOnClickOverlay={false} defaultStyle={false} v-model:show={evaluatModel.evaluatUpdateAudio}>
					<EvaluatAudio onClose={hanldeUpdateVideoAndAudio} />
				</Popup>
				<Popup teleport="body" closeOnClickOverlay={false} defaultStyle={false} v-model:show={evaluatModel.shareMode}>
					<EvaluatShare onClose={() => (evaluatModel.shareMode = false)} />
				</Popup>
			</div>
		);
	},
});
