import { Popup, Skeleton } from "vant";
import {
	computed,
	defineComponent,
	nextTick,
	onBeforeMount,
	onBeforeUnmount,
	onMounted,
	reactive,
	Transition,
	watch,
	watchEffect,
} from "vue";
import { formateTimes } from "../../helpers/formateMusic";
import Metronome, { metronomeData } from "../../helpers/metronome";
import state, {
	EnumMusicRenderType,
	evaluatCreateMusicPlayer,
	handleSetSpeed,
	IAudioState,
	IPlatform,
	isRhythmicExercises,
	resetPlaybackToStart,
	togglePlay,
} from "/src/state";
import { browser, 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_keepScreenLongLight,
	api_openCamera,
	api_openWebView,
	api_setEventTracking,
	api_setRequestedOrientation,
	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, { followData } from "/src/view/follow-practice";
import FollowModel from "../follow-model";
import RecordingTime from "../custom-plugins/recording-time";
import WorkIndex from "../custom-plugins/work-index";
import TheMusicList from "../component/the-music-list";
import { storeData } from "/src/store";
import ViewFigner from "../view-figner";

/** 需要处理频率的乐器
 * 120: 竖笛
 */
const instrumentSubject = [120];
const resetFrequency = (list: any[]) => {
	if (!instrumentSubject.includes(state.subjectId)) return list;
	for (let i = 0; i < list.length; i++) {
		if (list[i].prevFrequency) list[i].prevFrequency = list[i].prevFrequency * 2;
		if (list[i].frequency) list[i].frequency = list[i].frequency * 2;
		if (list[i].nextFrequency) list[i].nextFrequency = list[i].nextFrequency * 2;
	}
	return list;
};

/**
 * 乐器指法处理
 */
const setNoteHalfTone = (list: any[]) => {
	const instrumentNames = ["melodica"];
	if (!state.fingeringInfo?.name || !instrumentNames.includes(state.fingeringInfo.name)) return list;
	for (let i = 0; i < list.length; i++) {
		const note = list[i];
		if (note.noteElement?.pitch?.accidentalXml) {
			const accidentalXml = note.noteElement?.pitch?.accidentalXml;
			if ([]) {
			}
			if (accidentalXml === "flat") {
				// note.realKey = note.realKey + 1;
			} else if (accidentalXml === "sharp") {
				// note.realKey = note.realKey + 1;
			}
		}
	}
	return list;
};

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

		const detailData = reactive({
			isLoading: true,
			skeletonLoading: true,
			paddingLeft: "",
			headerHide: false,
			fingerPreView: false,
			orientation: 0,
		});
		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(() => {
			api_keepScreenLongLight();
			getAPPData();
			api_setStatusBarVisibility();
			const settting = store.get("musicscoresetting");
			if (settting) {
				state.setting = settting;
				if (state.setting.camera) {
					api_openCamera();
				}
			}
		});
		// console.log(route.params, query)
		/** 获取曲谱数据 */
		const getMusicInfo = (res: any) => {
			const index = query["part-index"] ? parseInt(query["part-index"] as string) : 0;
			const musicData = res.data.background[index] || {};
			const musicInfo = {
				...res.data,
				music: musicData.audioFileUrl || res.data.audioFileUrl,
				accompany: musicData.metronomeUrl || res.data.metronomeUrl,
				musicSheetId: musicData.musicSheetId || res.data.id,
				track: musicData.track || res.data.track,
			};
			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 = data.mp3Type === "MP3_METRONOME" ? false : true;
			state.isShowFingering = data.showFingering ? true : false;
			state.music = data.music;
			state.accompany = data.accompany;
			state.midiUrl = data.midiUrl;
			state.parentCategoriesId = data.musicTag;
			state.musicSheetCategoriesId = data.musicSheetCategoriesId;
			state.playMode = data.audioType === "MP3" ? "MP3" : "MIDI";
			state.originSpeed = state.speed = data.playSpeed;
			const track = data.code || data.track;
			state.track = track ? track.replace(/ /g, "").toLocaleLowerCase() : "";
			state.enableNotation = data.notation ? true : false;

			// 映射声部ID
			state.subjectId = mappingVoicePart((state.track as any) || state.subjectId, "INSTRUMENT");
			// console.log("🚀 ~ state.subjectId:", state.subjectId, state.track as any , state.subjectId)
			// 是否打击乐
			// 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";
			}

			// 如果是PC端,放大曲谱
			state.platform = query.platform?.toLocaleUpperCase() || "";
			if (state.platform === IPlatform.PC) {
				state.zoom = query.zoom || 1.5;
			}

			//课堂乐器,默认简谱
			state.musicRenderType = EnumMusicRenderType.firstTone;
		};

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

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

		/** 渲染完成 */
		const handleRendered = (osmd: any) => {
			detailData.skeletonLoading = false;
			state.osmd = osmd;
			// 没有设置速度使用读取的速度
			if (state.originSpeed === 0) {
				state.originSpeed = state.speed = (osmd as any).bpm || osmd.Sheet.userStartTempoInBPM || 100;
			}
			const saveSpeed =
				(store.get("speeds") || {})[state.examSongId] ||
				(osmd as any).bpm ||
				osmd.Sheet.userStartTempoInBPM;
			// 加载本地缓存的速度
			if (saveSpeed) {
				handleSetSpeed(saveSpeed);
			}
			state.times = formateTimes(osmd);
			state.times = resetFrequency(state.times);
			// state.times = setNoteHalfTone(state.times);
			console.log("🚀 ~ state.times:", state.times, state.subjectId);
			try {
				metronomeData.metro = new Metronome();
				metronomeData.metro.init(state.times);
			} catch (error) {}
			// 设置节拍器
			if (state.needTick) {
				const beatLengthInMilliseconds = (60 / state.speed) * 1000;
				// console.log(state.speed, osmd?.Sheet?.SheetPlaybackSetting?.beatLengthInMilliseconds , (60 / state.speed) * 1000)
				handleInitTick(
					beatLengthInMilliseconds,
					osmd?.Sheet?.SheetPlaybackSetting?.Rhythm?.Numerator || 4
				);
			}
			api_cloudLoading();

			state.musicRendered = true;

			evaluatCreateMusicPlayer();
			resetPlaybackToStart();
		};
		/** 指法配置 */
		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.setting.soundEffect,
			() => {
				store.set("musicscoresetting", state.setting);
			}
		);
		/**播放状态改变时,向父页面发送事件 */
		const sendParentMessage = (playState: IAudioState) => {
			window.parent.postMessage(
				{
					api: "headerTogge",
					playState: playState,
				},
				"*"
			);
		};
		// 监听播放状态
		watch(
			() => state.playState,
			() => {
				if (state.platform != IPlatform.PC) {
					detailData.headerHide = state.playState === "play" ? true : false;
				}
				sendParentMessage(state.playState);
			}
		);
		/** 指法预览切换 */
		watch(() => detailData.fingerPreView, () => {
			console.log(2342)
			window.parent.postMessage(
				{
					api: "api_fingerPreView",
					state: detailData.fingerPreView,
				},
				"*"
			);
		})
		onMounted(() => {
			window.addEventListener("resize", resetMusicScore);
		});
		onBeforeUnmount(() => {
			window.removeEventListener("resize", resetMusicScore);
		});
		const browsInfo = browser();
		const handleOpenFignerView = () => {
			if (!query.modelType) {
				detailData.orientation = state.fingeringInfo.orientation || 0;
				api_setRequestedOrientation(detailData.orientation);
			}
			// const url = `${
			// 	/(192|localhost)/.test(location.origin)
			// 		? "http://192.168.3.114:3000/instrument.html"
			// 		: location.origin + location.pathname
			// }#/view-figner`;
			// console.log("🚀 ~ url:", url);
			// api_openWebView({
			// 	url: url,
			// 	orientation: state.fingeringInfo.orientation || 0,
			// });
			
			if (state.playState === 'play') {
				togglePlay('paused')
				setTimeout(() => {
					detailData.fingerPreView = true;
				}, 500)
				return
			}
		};
		const handleCloseFignerView = () => {
			if (!query.modelType && detailData.orientation == 1) {
				api_setRequestedOrientation(0);
			}
			detailData.fingerPreView = false;
		};
		return () => (
			<div
				class={[
					styles.detail,
					state.setting.eyeProtection && "eyeProtection",
					state.platform === IPlatform.PC && styles.PC,
				]}
				style={{
					paddingLeft: detailData.paddingLeft,
					opacity: state.setting.camera ? `${state.setting.cameraOpacity / 100}` : "",
				}}
			>
				<Transition name="van-fade">
					{detailData.skeletonLoading && (
						<div class={styles.skeleton}>
							<Skeleton row={8} />
						</div>
					)}
				</Transition>
				<div class={[styles.headHeight, detailData.headerHide && styles.headHide]}>
					{state.musicRendered && <HeaderTop />}
				</div>
				<div
					id="scrollContainer"
					style={{ ...fingerConfig.value.container, height: detailData.headerHide ? "100vh" : "" }}
					class={[
						styles.container,
						!state.setting.displayCursor && "hideCursor",
						browsInfo.xiaomi && styles.xiaomi,
					]}
					onClick={(e: Event) => {
						if (state.playState === "play" && state.platform != IPlatform.PC) {
							detailData.headerHide = !detailData.headerHide;
						}
					}}
				>
					{/* 曲谱渲染 */}
					{!detailData.isLoading && <MusicScore onRendered={handleRendered} />}

					{/* 指法 */}
					{state.setting.displayFingering && state.fingeringInfo?.name && (
						<div style={{ ...fingerConfig.value.fingerBox }}>
							<Fingering onOpen={() => handleOpenFignerView()} />
						</div>
					)}
				</div>

				{/* 节拍器 */}
				{state.needTick && <Tick />}

				{/* 播放 */}
				{!detailData.isLoading && <AudioList />}

				{/* 评测 */}
				{state.modeType === "evaluating" && (
					<>
						<Evaluating />
						{evaluatingData.rendered && <EvaluatModel />}
					</>
				)}

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

				{state.musicRendered && (
					<>
						{/* 统计训练时长 */}
						{storeData.isApp && <RecordingTime />}
						{/* 作业 */}
						{query.workRecord && <WorkIndex />}
						{/* 曲谱列表 */}
						{state.playState == "play" ||
						followData.start ||
						evaluatingData.startBegin ||
						query.workRecord ||
						query.modelType ||
						state.platform === IPlatform.PC ? null : (
							<TheMusicList />
						)}
					</>
				)}

				<Popup teleport="body" v-model:show={detailData.fingerPreView} position="bottom">
					<ViewFigner
						subject={state.fingeringInfo.name}
						isComponent={true}
						onClose={handleCloseFignerView}
					/>
				</Popup>
			</div>
		);
	},
});
