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";
import { transform } from "lodash";

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 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)
							selectData.measureHeight = 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);
		};
		/** 是否可以点击音符 */
		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 []
		})

		onMounted(() => {
			selectData.notes = [];
			selectData.staves = [];
			calcNoteData();
			const img: HTMLElement = document.querySelector('#cursorImg-0')!
			if (metronomeData.cursorMode === 2){
				img.classList.add('lineHide')
			} else {
				img.classList.remove('lineHide')
			}
			// 初始化谱面可移动的元素位置
			try {
			moveData.partIndex = state.partIndex + ""
			// 速度标记元素和谱面并非同时渲染，初始化可移动元素的时候，需要加个延迟
			setTimeout(() => {
				renderForMoveData()
			}, 0);
			} catch (error) {}
		});
		return () => (
			<>

				<div
					id="selectionBox"
					class={[
						styles.selectionContainer,
						isPad && styles.isPad,
						state.zoom == 1.25 ? styles.middleZoom : state.zoom == 1.5 ? styles.bigZoom : state.zoom == 1.75 ? styles.largeZoom : state.zoom == 2 ? styles.largeZoom2 : state.zoom == 2.25 ? styles.largeZoom3 : 
						state.zoom == 0.65 ? styles.smallZoom : state.zoom == 0.5 ? styles.litteZoom : ''
					]}
					onClick={(e: Event) => e.stopPropagation()}
				>
					{selectData.staves.map((item: any, index) => {
						// 评测得分
						const scoreItem = item.id && 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;
							// console.log('显示节拍指针',lineShow,state.times[state.activeNoteIndex].MeasureNumberXML,item.MeasureNumberXML,metronomeData.activeMetro?.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" || state.isHomeWork)&&styles.playIng]} onClick={()=>{
										// 如果选择了2个 删除左边的时候
										if (state.section.length===1&&index === 0) {
											// #bug:11552
											resetBaseRate(state.activeNoteIndex);
										}
										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",
											});
										}
										// IOS18.1.1浏览器渲染更新有问题，需要手动更新一下
										const selectionDom = document.getElementById('selectionBox')
										if (selectionDom) {
											selectionDom.style.display = 'none';
											requestAnimationFrame(() => {
												selectionDom.style.display = 'block';
											})
										}										
									}}></div>
								</div>
							)
						})
					}
					{/* 移动模块 */}
					{query.isMove == "1" && <MoveMusicScore />}
				</div>
			</>
		);
	},
});
