import { computed, defineComponent, onMounted, reactive, ref, onUnmounted } from "vue";
import { formatXML, onlyVisible, getCustomInfo } from "../../helpers/formateMusic";
// // @ts-ignore
import { OpenSheetMusicDisplay } from "/osmd-extended/src";
import state, { EnumMusicRenderType, IPlatform, resetCursorPosition } from "/src/state";
import Selection from "../selection";
import styles from "./index.module.less";
import queryString from "query-string";
import { getGradualLengthByXml } from "/src/helpers/calcSpeed";
import { resetFormate, resetGivenFormate, setGlobalMusicSheet, limitSingleSvgPageHeight } from "/src/helpers/customMusicScore"
import { setGlobalData } from "/src/utils";
import { storeData } from "/src/store";
import HorizontalDragScroll from './HorizontalDragScroll';
import CombineAudio from './combineAudio';
import { getQuery } from "/src/utils/queryString";

export const musicRenderTypeKey = "musicRenderType";
export const musicData = reactive({
	showSelection: false, // 可以加载点击浮层
	score: ""
});

/** 重新渲染曲谱 */
export const resetRenderMusicScore = (type?: string) => {
	const search = queryString.parse(location.search);
	const newSearch = queryString.stringify({
		...search,
		_t: Date.now(),
		musicRenderType: type,
		isSingleLine: state.isSingleLine
	});
	location.search = "?" + newSearch;
};

// 下载后的xml
export const downloadXmlStr = ref("")

export default defineComponent({
	name: "music-score",
	emits: ["rendered"],
	props: {
		/** 是否渲染选择框 */
		showSelection: {
			type: Boolean,
			default: true,
		},
		renderTypeKey: {
			type: String,
			default: "",
		},
		musicColor: {
			type: String,
			default: "",
		},
		/** 是否渲染声轨名称 */
		showPartNames: {
			type: Boolean,
			default: false,
		},
	},
	setup(props, { emit, slots, expose }) {
		const query: any = getQuery();
		let osmd: any = null;
		/** 设置 曲谱模式,五线谱还是简谱 */
		const setRenderType = () => {
			const musicRenderType: any = sessionStorage.getItem(props.renderTypeKey || musicRenderTypeKey);
			if (musicRenderType in EnumMusicRenderType) {
				state.musicRenderType = musicRenderType;
			}
		};
		const getXML = async () => {
			// 当有下载的xml的时候直接使用，否则需要下载
			if(!downloadXmlStr.value){
				downloadXmlStr.value = await fetch(state.xmlUrl).then((response) => response.text())
			}
			const xmlStr = downloadXmlStr.value;
			console.time('解析xml')
			const parseXmlInfo = getCustomInfo(xmlStr);
			const xml = formatXML(parseXmlInfo.parsedXML);
			musicData.score = state.isCombineRender ? xml : onlyVisible(xml, state.partIndex);
			if (state.gradualTimes) {
				state.gradual = getGradualLengthByXml(xml);
			}
			console.timeEnd('解析xml')
		};

		const init = async () => {
			console.time("渲染加载耗时");
			const container = document.getElementById("musicAndSelection");
			if (!container || !musicData.score) return;
			setGlobalMusicSheet();
			if(!osmd){
				osmd = new OpenSheetMusicDisplay(container, {
					drawTitle: false,
					drawSubtitle: false,
					// drawMeasureNumbers: false,
					autoResize: false,
					followCursor: false,
					drawLyricist: false, // 渲染作曲家
					drawComposer: false, // 渲染作词家
					// pageBackgroundColor: '#609FCF',
					// autoGenerateMultipleRestMeasuresFromRestMeasures: state.isSingleLine ? false : true, // 连续休止小节是否合并显示
					// darkMode: true, // 暗黑模式
					// pageFormat: 'A4_P',
					// autoBeam: true,
					// drawMetronomeMarks: false,
					// ...this.opotions,
					colorStemsLikeNoteheads: true, // 是否将音符柄的颜色设置为与它们的音符头相同，默认false
					// drawingParameters: "compact" // 使用紧凑布局
					// drawLyrics: (((!state.accompany && !state.music ) || state.playType === 'sing' || !state.isEvxml) && !state.isSimplePage) ? true : false, // 演唱模式才渲染歌词，simple页面不显示歌词
					// drawPartNames: props.showPartNames, // 是否渲染声轨名称
					// defaultColorMusic: props.musicColor, // 颜色
					// renderSingleHorizontalStaffline: state.isSingleLine ? true : false
				});
			}
			osmd.setOptions({
				drawLyrics: (((!state.accompany && !state.music ) || state.playType === 'sing' || !state.isEvxml) && !state.isSimplePage) ? true : false, // 演唱模式才渲染歌词，simple页面不显示歌词
				drawPartNames: props.showPartNames, // 是否渲染声轨名称
				defaultColorMusic: props.musicColor, // 颜色
				renderSingleHorizontalStaffline: state.isSingleLine ? true : false,
				autoGenerateMultipleRestMeasuresFromRestMeasures: state.setting.combineMultipleRest, // 是否自动合并休止小节
			})
			// osmd.EngravingRules.CompactMode = true // 紧凑模式
			// osmd.EngravingRules.PageRightMargin = state.isSingleLine ? (window.innerWidth+200)/10 : 2;
			// osmd.EngravingRules.FixedMeasureWidth = state.isSingleLine ? true : false; // 是否固定小节的宽度（小节同一宽度渲染）
			//osmd.EngravingRules.PageTopMargin = state.platform === IPlatform.PC ? 0 : 1; // 老师端顶部间距
			// 老师端上课页面，左右两边有功能按钮，所以左右边距需要加大
			// if (state.isAttendClass && state.platform === IPlatform.PC) {
			// 	osmd.EngravingRules.PageLeftMargin = 7;
			// 	osmd.EngravingRules.PageRightMargin = 7;
			// }
			//osmd.EngravingRules.PageBottomMargin = state.platform === IPlatform.PC ? 1 : 2;
			if (state.isSimplePage) {
				osmd.EngravingRules.PageTopMargin = state.musicRenderType === 'staff' ? 2 : 4;
				osmd.EngravingRules.PageTopMarginNarrow = 0;
				osmd.EngravingRules.PageLeftMargin = 3.6;
				osmd.EngravingRules.PageRightMargin = 0;
				osmd.EngravingRules.BreathMarkDistance = 0.1; 
				osmd.EngravingRules.PageBottomMargin = 0;
			} else {
				// osmd.EngravingRules.PageTopMargin = state.isEvaluatReport ? 7 : 3; // 顶部间距
				// osmd.EngravingRules.PageTopMargin = state.isPreView ? 1 : 3;
				osmd.EngravingRules.PageTopMargin = (state.isPreView && state.musicRenderType === EnumMusicRenderType.staff) ? 1 : state.isPreView ? 2 : 3;
				osmd.EngravingRules.PageTopMarginNarrow = 3;
				osmd.EngravingRules.PageLeftMargin = state.isCombineRender ? 8 : 3.6;
				osmd.EngravingRules.PageRightMargin = 3;
				osmd.EngravingRules.BreathMarkDistance = 0.1; // 呼吸标记距离音符的位置，百分比
				osmd.EngravingRules.PageBottomMargin = state.isSingleLine ? 2 : 18;
			}
			osmd.EngravingRules.DYMusicScoreType =
				state.musicRenderType === EnumMusicRenderType.staff ? "staff" : "jianpu";
			// 如果为固定调,需要加入全局
			if (state.musicRenderType === EnumMusicRenderType.fixedTone) {
				(window as any).sett = {
					keySignature: true,
				};
			} else {
				(window as any).sett = {
					keySignature: false,
				};
			}
			osmd.EngravingRules.DYMusicScoreId = state.examSongId || ''
			osmd.EngravingRules.DYCustomRepeatCount = state.maxLyricNum || 0;
			osmd.EngravingRules.DYIsSingleLine = state.isSingleLine;
			await osmd.load(musicData.score);
			// 对外暴露 一行谱时候 缩小谱面
			if(state.isSimplePage){
				state.zoom = 0.5
			}
			// 需要渲染总谱的云教练页面
			if (!state.isSimplePage && state.isCombineRender) {
				const canSelectTracks = state.combinePartIndexs.length > 1 ? state.combinePartIndexs.map(partIndex => { return state.partListNames[partIndex] }) : state.canSelectTracks
				for (let i = 0; i < osmd.Sheet.Instruments.length; i++) {
					const trackName = state.isEvxml && state.evxmlAddPartName ? osmd.Sheet.Instruments[i].idString || '' : osmd.Sheet.Instruments[i].Name || '';
					osmd.Sheet.Instruments[i].Visible = canSelectTracks.includes(trackName.trim())
				}
			}
			if (query.downPng === 'A4') {
				osmd.EngravingRules.PageTopMargin = 5
				osmd.setPageFormat('794x1100')
				osmd.zoom = query.zoom || 0.3;
			} else {
				osmd.zoom = state.zoom;
			}
			osmd.render();
			console.log("🚀 ~ osmd:", osmd)
			emit("rendered", osmd);
			resetFormate();
			resetGivenFormate();
			musicData.showSelection = true;
		};
		let horizontalDragScroll:HorizontalDragScroll | null
		onMounted(async () => {
			//setRenderType();
			await getXML();
			await init();
			// pc 端支持 拖动滚动
			if(state.platform === "PC" || query.isCbs){
				const container = document.querySelector('#musicAndSelection') as HTMLElement;
				horizontalDragScroll = new HorizontalDragScroll(container);
			}
		});
		onUnmounted(() => {
			horizontalDragScroll?.destroy()
		})
		const isInTheGradualRange = computed(() => {
			let result: boolean = false;
			const activeMeasureIndex = state.times[state.activeNoteIndex]?.measureListIndex || -1;
			for (const [first, last] of state.gradual) {
				if (first && last) {
					// console.log('小节',first.measureIndex,last.measureIndex,activeMeasureIndex)
					result = first.measureIndex <= activeMeasureIndex && activeMeasureIndex < last.measureIndex;
					if (result) {
						break;
					}
				}
			}
			return result;
		});
		/** 刷新曲谱 */
		const refreshMusicScore = () => {
			state.loadingText = "正在加载中，请稍等..."
			state.isLoading = true
			state.evXmlBeginArr = [];
			state.vfmeasures = [];
			state.activeNoteIndex = 0;
			musicData.showSelection = false;
			state.osmd.clear();
			const container = document.getElementById('musicAndSelection'), svgDom = document.getElementById('osmdCanvasPage1');
			if (container) {
				//这里需要删除osmd，不然多行谱和一行谱切换 滚动高度会出问题
				svgDom && container?.removeChild(svgDom)
			}
			// 有可能会有 其他地方的js执行 阻塞 这里确保加载条出来
			setTimeout(async () => {
				// 在滚动过程中(雄鹰高飞这种marginbottom比较大的) 多行谱和一行谱切换 滚动高度会出问题
				container && (container.scrollTop = 0)
				//setRenderType();
				state.basePlayRate = 1;
				await getXML();
				await init();
				musicData.showSelection = true;
				state.isLoading = false
				resetCursorPosition()
			}, 60);
		}
		expose({
			refreshMusicScore,
		})

		return () => (
			<div
				id="musicAndSelection"
				style={{ "--music-zoom": state.musicZoom }}
				class={[
					isInTheGradualRange.value && styles.inGradualRange,
					state.musicRenderType == EnumMusicRenderType.staff ? "staff" : "jianpuTone",
					state.isSingleLine && "singleLineMusicBox",
					(!state.isCreateImg && !state.isPreView && !state.isCbsView && state.musicRenderType === EnumMusicRenderType.staff) ? "blueMusicXml" : "",
					state.isSingleLine && state.playState ==="play" && styles.notTouch,
					!state.isSingleLine && (state.platform === "PC" || query.isCbs) &&  styles.pcCursorGrab

				]}
			>
				{slots.default?.()}
				{props.showSelection && musicData.showSelection && !state.isEvaluatReport &&!state.isSimplePage && !state.isPreView && state.musicRendered && <Selection />}
				{props.showSelection && musicData.showSelection && state.isCombineRender &&!state.isSimplePage && !state.isPreView && state.musicRendered && <CombineAudio></CombineAudio> }
			</div>
		);
	},
});
