import { Skeleton } from "vant";
import { computed, defineComponent, nextTick, onBeforeMount, onBeforeUnmount, onMounted, reactive, Transition, watch, watchEffect } from "vue";
import { useRoute } from "vue-router";
import { formateTimes } from "../../helpers/formateMusic";
import Metronome, { metronomeData } from "../../helpers/metronome";
import state, { isRhythmicExercises } from "../../state";
import { storeData } from "../../store";
import { setGlobalData } from "../../utils";
import AudioList from "../../view/audio-list";
import MusicScore, { resetMusicScore } from "../../view/music-score";
import { sysMusicScoreAccompanimentQueryPage } from "../api";
import EvaluatModel from "../evaluat-model";
import HeaderTop from "../header-top";
import styles from "./index.module.less";
import { api_cloudLoading, api_openCamera, api_setEventTracking, api_setStatusBarVisibility, isSpecialShapedScreen } from "/src/helpers/communication";
import { getQuery } from "/src/utils/queryString";
import Evaluating, { evaluatingData } from "/src/view/evaluating";
import MeasureSpeed from "/src/view/plugins/measure-speed";
import { mappingVoicePart, subjectFingering } from "/src/view/fingering/fingering-config";
import Fingering from "/src/view/fingering";
import store from "store";
import Tick, { handleInitTick } from "/src/view/tick";
import FollowPractice from "/src/view/follow-practice";
import FollowModel from "../follow-model";
import RecordingTime from "../custom-plugins/recording-time";

export default defineComponent({
	name: "music-list",
	setup() {
		const query: any = getQuery();

		const detailData = reactive({
			isLoading: true,
			paddingLeft: "",
			headerHide: false,
		});
		const getAPPData = async () => {
			const screenData = await isSpecialShapedScreen();
			if (screenData?.content) {
				// console.log("🚀 ~ screenData:", screenData.content);
				const { isSpecialShapedScreen, notchHeight } = screenData.content;
				if (isSpecialShapedScreen) {
					detailData.paddingLeft = 25 + "px";
				}
			}
		};
		onBeforeMount(() => {
			getAPPData();
			api_setStatusBarVisibility();
			const settting = store.get("musicscoresetting");
			if (settting) {
				state.setting = settting;
				if (state.setting.camera) {
					api_openCamera();
				}
				// console.log("🚀 ~ settting:", settting)
			}
		});
		// console.log(route.params, query)
		/** 获取曲谱数据 */
		const getMusicInfo = (res: any) => {
			const index = query["part-index"] ? parseInt(query["part-index"] as string) : 0;
			const musicInfo = {
				...res.data,
				accompany: res.data.audioFileUrl,
				...res.data.background[index],
			};
			// console.log("🚀 ~ musicInfo:", musicInfo);
			setState(musicInfo, index);
			setCustom();
			detailData.isLoading = false;
		};

		const setState = (data: any, index: number) => {
			state.appName = "COLEXIU";
			state.detailId = data.id;
			state.xmlUrl = data.xmlFileUrl;
			state.partIndex = index;
			state.subjectId = data.musicSubject;
			state.categoriesId = data.categoriesId;
			state.categoriesName = data.musicTagNames;
			state.enableEvaluation = data.canEvaluate ? true : false;
			state.examSongId = data.id + "";
			state.examSongName = data.musicSheetName;
			// 解析扩展字段
			if (data.extConfigJson) {
				try {
					state.extConfigJson = JSON.parse(data.extConfigJson as string);
				} catch (error) {
					console.error("解析扩展字段错误:", error);
				}
			}
			state.isOpenMetronome = data.mp3Type === "MP3_METRONOME" ? true : false;
			state.needTick = true; // data.isOpenMetronome;
			state.isShowFingering = data.showFingering ? true : false;
			state.music = data.audioFileUrl;
			state.accompany = data.accompany;
			state.midiUrl = data.midiUrl;
			state.parentCategoriesId = data.musicTag;
			state.playMode = data.audioType === "MP3" ? "MP3" : "MIDI";
			// state.originSpeed = state.speed = parseFloat(data.playSpeed) || 0;
			state.originSpeed = state.speed = data.playSpeed;
			state.track = data.track;
			state.enableNotation = data.notation ? true : false;

			// 映射声部ID
			state.subjectId = mappingVoicePart(state.track as any, "COLEXIU");
			// 是否打击乐
			state.isPercussion = state.subjectId == 23 || state.subjectId == 113 || state.subjectId == 121 || isRhythmicExercises();

			// 设置指法
			state.fingeringInfo = subjectFingering(state.subjectId);
			// console.log("🚀 ~ state.fingeringInfo:", state.fingeringInfo, state.subjectId, state.track)

			// 检测是否原音和伴奏都有
			if (!state.music || !state.accompany) {
				state.playSource = state.music ? "music" : "background";
			}
		};

		const setCustom = () => {
			if (state.extConfigJson.multitrack) {
				setGlobalData("multitrack", state.extConfigJson.multitrack);
			}
		};

		onMounted(() => {
			(window as any).appName = "colexiu";
			Promise.all([sysMusicScoreAccompanimentQueryPage(query.id)]).then((values) => {
				getMusicInfo(values[0]);
			});
			api_setEventTracking();
		});

		/** 渲染完成 */
		const handleRendered = (osmd: any) => {
			state.musicRendered = true;
			state.osmd = osmd;
			const saveSpeed = (store.get("speeds") || {})[state.examSongId];
			const bpm = (osmd as any).bpm || osmd.Sheet.userStartTempoInBPM;
			state.originSpeed = state.speed = saveSpeed || bpm || 100;
			state.times = formateTimes(osmd);
			console.log("🚀 ~ state.times:", state.times);
			try {
				metronomeData.metro = new Metronome();
				metronomeData.metro.init(state.times);
			} catch (error) {}
			// 设置节拍器
			if (state.needTick) {
				const beatLengthInMilliseconds = osmd?.Sheet?.SheetPlaybackSetting?.beatLengthInMilliseconds || (60 / bpm) * 1000;
				handleInitTick(beatLengthInMilliseconds, osmd?.Sheet?.SheetPlaybackSetting?.Rhythm?.Numerator || 4);
			}
			api_cloudLoading();
		};
		/** 指法配置 */
		const fingerConfig = computed<any>(() => {
			if (state.setting.displayFingering && state.fingeringInfo?.name) {
				if (state.fingeringInfo.direction === "transverse") {
					return {
						container: {
							paddingBottom: state.fingeringInfo.height,
						},
						fingerBox: {
							height: state.fingeringInfo.height,
						},
					};
				} else {
					return {
						container: {
							paddingRight: state.fingeringInfo.width,
						},
						fingerBox: {
							position: "absolute",
							width: state.fingeringInfo.width,
							height: "100%",
							right: 0,
							top: 0,
						},
					};
				}
			}
			return {
				container: {},
				fingerBox: {},
			};
		});

		// 监听指法显示
		watch(
			() => state.setting.displayFingering,
			() => {
				if (state.fingeringInfo.direction === "vertical") {
					nextTick(() => {
						resetMusicScore();
					});
				}
			}
		);
		// 监听播放状态
		watch(
			() => state.playState,
			() => {
				detailData.headerHide = state.playState === "play" ? true : false;
			}
		);
		onMounted(() => {
			window.addEventListener("resize", resetMusicScore);
		});
		onBeforeUnmount(() => {
			window.removeEventListener("resize", resetMusicScore);
		});
		return () => (
			<div
				class={[styles.detail, state.setting.eyeProtection && "eyeProtection"]}
				style={{ paddingLeft: detailData.paddingLeft, opacity: state.setting.camera ? `${state.setting.cameraOpacity / 100}` : "" }}
			>
				{!state.musicRendered && (
					<div class={styles.skeleton}>
						<Skeleton class={styles.skeleton} row={8} />
					</div>
				)}
				<div class={[styles.headHeight, detailData.headerHide && styles.headHide]}>
					<Transition name="van-slide-down">{state.musicRendered && <HeaderTop />}</Transition>
				</div>
				<div
					id="scrollContainer"
					style={{ ...fingerConfig.value.container, height: detailData.headerHide ? "100vh" : "" }}
					class={[styles.container, !state.setting.displayCursor && "hideCursor"]}
					onClick={(e: Event) => {
						if (state.playState === "play") {
							detailData.headerHide = !detailData.headerHide;
						}
					}}
				>
					{/* 曲谱渲染 */}
					{!detailData.isLoading && <MusicScore onRendered={handleRendered} />}
					{/* 播放 */}
					{!detailData.isLoading && <AudioList />}
					{/* 评测 */}
					{state.modeType === "evaluating" && (
						<>
							<Evaluating />
							{evaluatingData.rendered && <EvaluatModel />}
						</>
					)}
					{/* 指法 */}
					{state.setting.displayFingering && state.fingeringInfo?.name && (
						<div style={{ ...fingerConfig.value.fingerBox }}>
							<Fingering />
						</div>
					)}
				</div>

				{/* 公用的插件 */}
				<div class={styles.plugins}>
					{state.musicRendered && (
						<>
							<MeasureSpeed />
							{/* 统计训练时长 */}
							<RecordingTime />
						</>
					)}
				</div>
				{/* 节拍器 */}
				{state.needTick && <Tick />}

				{/* 跟练模式 */}
				{state.modeType === "follow" && (
					<>
						<FollowPractice />
						<FollowModel />
					</>
				)}
			</div>
		);
	},
});
