import { computed, defineComponent, onMounted, reactive, Transition, nextTick, watch } from "vue";
import state, { EnumMusicRenderType, handleSelection, skipNotePlay, IPlatform, resetBaseRate } from "/src/state";
import styles from "./index.module.less";
import { metronomeData } from "/src/helpers/metronome";
import { evaluatingData } from "../evaluating";
import { leveByScoreMeasureIcons } from "../evaluating/evaluatResult";
import { Icon, showToast } from "vant";
import MoveMusicScore, { moveData, renderForMoveData } from "../plugins/move-music-score";
import { useRoute } from "vue-router";
import { getQuery } from "/src/utils/queryString";
import IntonationDown from "./imgs/pitchLow.png"
import IntonationUp from "./imgs/pitchHigh.png"
import MultipleRestMeasures from "./multipleRestMeasures"
import { browser } from "../../utils";

const selectData = reactive({
	notes: [] as any[],
	staves: [] as any[],
	measureHeight: 0 as number, // 小节高度
});

/** 计算点击层数据 */
const calcNoteData = () => {
	const musicContainer = document.getElementById("musicAndSelection")?.getBoundingClientRect() || {
		x: 0,
		y: 0,
	};
	const parentLeft = musicContainer.x || 0;
	const parentTop = musicContainer.y || 0;
	const notes = state.times;
	const notesList: string[] = [];
	const MeasureNumberXMLList: number[] = [];
	let minMeasureHeigt: number = 0;
	for (let i = 0; i < notes.length; i++) {
		const item = notes[i];
		// console.log("🚀 ~ item:", item)
		const noteItem = {
			...item,
			index: item.i,
			bbox: null as any,
			staveBox: null as any,
		};
		if (!notesList.includes(item.noteId)) {
			let staveBbox: any = {}, customBgBox: any = {};
			if (item.stave?.attrs?.id) {
				const staveEle = document.querySelector(`#${item.stave.attrs.id}`);
				staveBbox = staveEle?.parentElement?.parentElement?.getBoundingClientRect?.() || {
					x: 0,
					width: 0,
				};
				customBgBox = staveEle?.querySelector('.vf-custom-bg')?.getBoundingClientRect() || { y: 0, height: 0 }
				// console.log("🚀 ~ staveBbox:", staveBbox.height)
			}
			if (item.svgElement) {
				const noteEle = document.querySelector(`#vf-${item.svgElement?.attrs?.id}`);

				if (noteEle) {
					const noteBbox = noteEle.getBoundingClientRect?.() || { x: 0, width: 0 };
					if (state.musicRenderType !== EnumMusicRenderType.staff) {
						noteItem.bbox = {
							left: noteBbox.x - parentLeft - noteBbox.width / 4 + "px",
							top: noteBbox.y - parentTop - noteBbox.height + "px",
							width: noteBbox.width * 1.5 + "px",
							height: noteBbox.height * 3 + "px",
							x: item.bbox?.x,
							y: item.bbox?.y,
							originWidth: item.bbox?.width
						};
						const noteHead = noteEle.querySelector(".vf-numbered-note-head");
						const noteHeadBbox = noteHead?.getBoundingClientRect?.();
						if  (noteHeadBbox) {
							item.bbox = {
								left: noteHeadBbox.x - parentLeft - noteHeadBbox.width / 4,
								width: noteHeadBbox.width * 1.5,
								x: item.bbox?.x,
								y: item.bbox?.y,
								originWidth: item.bbox?.width
							}
						}
						
					} else {
						const needTransY = -(staveBbox.height - customBgBox.height) / 2 + "px";
						noteItem.bbox = {
							left: noteBbox.x - parentLeft - noteBbox.width / 4 + "px",
							top: customBgBox.y ? customBgBox.y - parentTop + "px" : staveBbox.y - parentTop + "px",
							width: noteBbox.width * 1.5 + "px",
							height: staveBbox.height + "px",
							x: item.bbox?.x,
							y: item.bbox?.y,
							originWidth: item.bbox?.width,
							transform: `translateY(${needTransY})`
						};
					}
					
				}
				if (selectData.notes.find((item:any) => item.id === noteItem.id)) {
					// 
				} else {
					selectData.notes.push(noteItem);
				}
				// selectData.notes.push(noteItem);
				notesList.push(item.noteId);
			}
		}

		if (!MeasureNumberXMLList.includes(item.MeasureNumberXML)) {
			if (item.stave) {
				if (item.stave?.attrs?.id) {
					const staveEle = document.querySelector(`#${item.stave.attrs.id}`);
					const list = [
						Array.from(staveEle?.querySelectorAll(".vf-clef") || []),
						Array.from(staveEle?.querySelectorAll(".vf-keysignature") || []),
						Array.from(staveEle?.getElementsByTagName("text") || []),
					].flat();
					try {
						if (list.length) {
							// console.log("🚀 ~ list:", list)
							list.forEach((_el: any) => {
								_el?.style?.setProperty("display", "none");
							});
						}
					} catch (error) {}

					const staveBbox = staveEle?.getBoundingClientRect?.() || { x: 0, width: 0, y: 0, height: 0 };
					if (i === 0) {
						minMeasureHeigt = staveBbox.height
					}
					try {
						if (list.length) {
							list.forEach((_el: any) => {
								_el?.style?.removeProperty("display");
							});
						}
					} catch (error) {}

					// console.log("🚀 ~ staveEle:", staveBbox.height)
					let compareVal = staveBbox.height - minMeasureHeigt
					compareVal = compareVal > 0 ? compareVal : 0
					selectData.measureHeight = staveBbox.height - compareVal
					noteItem.staveBox = {
						left: staveBbox.x - parentLeft + "px",
						// top: ((item.stave.y || 0) - 5) * state.zoom + "px",
						top: staveBbox.y - parentTop + compareVal + "px",
						width: staveBbox.width + "px",
						height: staveBbox.height - compareVal + "px",
						// background: 'rgba(0,0,0,.2)'
					};
					selectData.staves.push(noteItem);
				}
				MeasureNumberXMLList.push(item.MeasureNumberXML);
			} else {
				if (item.multipleRestMeasures) {
					if (state.isCombineRender) {
						let currentItem = null;
						for (let index = 0; index < state.vfmeasures.length; index++) {
							const element = state.vfmeasures[index];
							const measureNum = element.getAttribute('data-num') ? Number(element.getAttribute('data-num')) : -1;
							const nextMeasureNum = state.vfmeasures[index+1]?.getAttribute('data-num') ? Number(state.vfmeasures[index+1]?.getAttribute('data-num')) : -1;
							if (measureNum === item.MeasureNumberXML || item.MeasureNumberXML < nextMeasureNum || nextMeasureNum == -1) {
								currentItem = element
								break;
							}
						}
						const staveBbox = currentItem?.querySelector('.vf-stave')?.getBoundingClientRect() || { x: 0, width: 0, y: 0, height: 0 };
						if (currentItem) {
							noteItem.staveBox = {
								left: staveBbox.x - parentLeft + "px",
								// top: ((item.stave.y || 0) - 5) * state.zoom + "px",
								top: staveBbox.y - parentTop  + "px",
								width: staveBbox.width + "px",
								height: staveBbox.height + "px",
								// height: preItem.staveBox.height,
							};
							selectData.staves.push(noteItem);
							MeasureNumberXMLList.push(item.MeasureNumberXML);
						}
					} else {
						const preItem = selectData.staves.find(
							(n: any) => n.MeasureNumberXML === item.MeasureNumberXML - 1
						);
						if (preItem?.staveBox) {
							noteItem.staveBox = {
								left: preItem.staveBox.left,
								top: preItem.staveBox.top,
								width: preItem.staveBox.width,
								// height: preItem.staveBox.height,
							};
							selectData.staves.push(noteItem);
							MeasureNumberXMLList.push(item.MeasureNumberXML);
						}
					}

				}
			}
		}
	}
	// 部分浏览器渲染的第一小节的位置信息会包含拍号、调号，需要处理一下，剔除掉拍号、调号的位置
	if (selectData.staves[0]?.staveBox?.top !== selectData.staves[1]?.staveBox?.top) {
		selectData.staves[0].staveBox.top = selectData.staves[1]?.staveBox?.top || selectData.staves[0]?.staveBox?.top
	}
	console.log("🚀 ~ selectData.notes:", selectData.notes, selectData.staves);
};

/** 重新计算 */
export const recalculateNoteData = () => {
	selectData.notes = [];
	selectData.staves = [];
	calcNoteData();
};

export default defineComponent({
	name: "selection",
	setup() {
		const browsInfo = browser();
		const isPad =  navigator?.userAgent?.includes("UAWEIVRD-W09") || browsInfo?.iPad || browsInfo.isTablet;
		const route = useRoute();
		const query: any = {
			...getQuery(),
			...route.query,
		};
		/** 是否可以点击音符 */
		const disableClickNote = computed(() => {
			return (state.sectionStatus && state.section.length != 2) || (state.modeType === "evaluating");
		});
		// 选段符号
		const sectionPosData = computed(() => {
			if(state.sectionStatus) {
				return state.section.map(((item,index) => {
					if(index === 0){
						const currItem = selectData.staves.find(stave => {
							return stave.MeasureNumberXML === item.MeasureNumberXML	
						})
						// 获取stave里面vf-custom-bg的位置坐标，才是准确的坐标
						// const currBgX = document.getElementById(currItem.stave.attrs.id)?.querySelector('.vf-custom-bg')?.getBoundingClientRect()?.x || 0;
						const currBgX = currItem.stave?.attrs && currItem.stave.attrs.id ? document.getElementById(currItem.stave.attrs.id)?.querySelector('.vf-custom-bg')?.getBBox()?.x * state.zoom || 0 : 0;						
						return currItem && {
							left: currBgX ? currBgX + 'px' : currItem.staveBox.left,
							top: currItem.staveBox.top,
							height: selectData.measureHeight + 'px'  // 小节的高度
						}
					} else {
						// 实际的结束位置
						const actualEndIndex = state.userChooseEndIndex > item.MeasureNumberXML ? state.userChooseEndIndex : item.MeasureNumberXML
						const currItem = selectData.staves.find(stave => {
							return stave.MeasureNumberXML === actualEndIndex
						})
						return currItem && {
							left: parseFloat(currItem.staveBox.left)+parseFloat(currItem.staveBox.width)-2 +"px",
							top: currItem.staveBox.top,
							height: selectData.measureHeight + 'px'
						}
					}
				}))
			}
			return []
		})
		console.time('dom挂载')
		onMounted(() => {
			console.timeEnd('dom挂载')
			selectData.notes = [];
			selectData.staves = [];
			console.time('添加dom时间')
			calcNoteData();
			console.timeEnd('添加dom时间')
			// 初始化谱面可移动的元素位置
			try {
			moveData.partIndex = state.partIndex + ""
			// 速度标记元素和谱面并非同时渲染，初始化可移动元素的时候，需要加个延迟
			setTimeout(() => {
				renderForMoveData()
			}, 0);
			} catch (error) {}
		});
		return () => (
			<>
				<div
					id="selectionBox"
					class={[
						styles.selectionContainer,
						isPad && styles.isPad
					]}
					onClick={(e: Event) => e.stopPropagation()}
				>
					{selectData.staves.map((item: any, index) => {
						// 评测得分
						const scoreItem = item && evaluatingData.evaluatings[item.measureListIndex];
						// for(let idx in evaluatingData.evaluatings) {
						// 	const { show, measureIndex } = evaluatingData.evaluatings[idx]
						// 	if (show && measureIndex !== item.measureListIndex) {
						// 		evaluatingData.evaluatings[idx].show = false
						// 	}
						// }
						// 高级模式下，显示节拍线
						// 不是报告模式
						// 不是多小节休止符
						// 节拍线开关
						// 当前小节
						// 当前小节
						/* 节拍指针，现在没有节拍器指针了，但是以后要加上的话，这里需要性能优化。现在这样每次节拍指针更新都会刷新这里的虚拟dom */
						// const lineShow =
						// 	!state.isReport &&
						// 	metronomeData.cursorMode === 2 &&
						// 	item.MeasureNumberXML === metronomeData.activeMetro?.measureNumberXML &&
						// 	state.times[state.activeNoteIndex].MeasureNumberXML === item.MeasureNumberXML;
						return (
							<>
								{item.staveBox && (
									<div
										key={item.id}
										class={[
											styles.position,
											// scoreItem ? `scoreItemLeve${scoreItem.leve}` : "", // 去掉评测小节得分的背景色
											(state.platform === IPlatform.PC && state.zoom > 0.8) ? styles.linePC : '',
											`measureIndex_${item.MeasureNumberXML}`
										]}
										style={item.staveBox}
										onClick={() => {
											// 当为连续休止小节的结束选段的时候 应该传休止小节 结束的位置
											let staveItem = item
											if(state.section.length === 1 && item.totalMultipleRestMeasures > 0){
												staveItem = selectData.staves[index + item.totalMultipleRestMeasures - 1]
											}
											handleSelection(staveItem)	
										}}
									>
										{/* {lineShow && (
											<div style={{height: selectData.measureHeight + 'px', position: 'relative'}}>
												<div 
												class={[
													styles.line,
													state.setting.eyeProtection ? styles.eyeLine : '',
													state.musicRenderType == EnumMusicRenderType.staff ? styles.lineStaff : styles.lineJianPu,
												]} 
												style={{ left: metronomeData.activeMetro.left }}></div>
											</div>
										)} */}
										{!state.isReport &&
											!!item.multipleRestMeasures &&
											<MultipleRestMeasures item = {item}></MultipleRestMeasures>
										}
										<Transition
											name="centerTop"
											onAfterEnter={() => {
												scoreItem.show = false;
											}}
										>
											{scoreItem?.show && (
												<div
													class={styles.scoreItem}
													style={{ color: leveByScoreMeasureIcons[scoreItem.leve]?.color || "" }}
												>
													<img src={leveByScoreMeasureIcons[scoreItem.leve]?.icon} />
													<span>{scoreItem.score}</span>
												</div>
											)}
										</Transition>
									</div>
								)}
							</>
						);
					})}
					{selectData.notes.map((item: any) => {
						return (
							<div
								class={[styles.position, disableClickNote.value && styles.disable, styles.note, `noteIndex_${item.index}`]}
								style={item.bbox}
								onClick={() => skipNotePlay(item.index, false, 'manual')}
							>
								{/* <div class={styles.noteFollow} data-vf={"vf" + item.id}>
									<Icon name="success" />
									<Icon name="cross" />
								</div> */}
								<div class={styles.noteFollow} data-vf={"vf" + item.id}>
									{/* <Icon name="success" />
									<Icon name="cross" /> */}
									<div class={[styles.followTipUp, 'tip-up']}>
										<img src={IntonationUp} />
										{/* <span>音准<i>高了</i></span> */}
									</div>
									<div class={[styles.followTipDown, 'tip-down']}>
										<img src={IntonationDown} />
										{/* <span>音准<i>低了</i></span> */}
									</div>
								</div>							
								<div class={[styles.noteDot, 'node-dot']}></div>
							</div>
						);
					})}
					{/* 选段 */}
					{
						sectionPosData.value.map((item,index) =>{
							return (
								item && <div class={styles.selectBox} style={item}>
									<div class={[styles.selectHandle,index>0&&styles.selectHandleRight,(state.playState==="play" || query.workRecord)&&styles.playIng]} onClick={()=>{
										// 如果选择了2个 删除左边的时候
										if(state.section.length===2&&index === 0){
											state.section = []
											// 重置速度和播放倍率
											resetBaseRate(state.activeNoteIndex);
											showToast({
												message: "请选择开始小节",
												duration: 0,
												position: "top",
												className: "selectionToast",
											});
										}else{
											state.section.splice(index,1)
											state.section = [...state.section]  // 触发 watch
											showToast({
												message: state.section.length?"请选择结束小节":"请选择开始小节",
												duration: 0,
												position: "top",
												className: "selectionToast",
											});
										}
									}}></div>
								</div>
							)
						})
					}
					{/* 移动模块 */}
					{query.isMove == "1" && <MoveMusicScore />}
				</div>
			</>
		);
	},
});
