import { PropType, computed, defineComponent, onBeforeMount, reactive } from "vue";
import styles from "./index.module.less";
import icons from "./image/icons.json";
import { FIGNER_INSTRUMENT_DATA, IFIGNER_INSTRUMENT_Note } from "/src/view/figner-preview";
import {
	ITypeFingering,
	IVocals,
	getFingeringConfig,
	subjectFingering,
} from "/src/view/fingering/fingering-config";
import { Howl } from "howler";
import { storeData } from "/src/store";
import { api_back } from "/src/helpers/communication";
import { Button, Icon } from "vant";

export default defineComponent({
	name: "viewFigner",
	emits: ["close"],
	props: {
		isComponent: {
			type: Boolean,
			default: false,
		},
		subject: {
			type: String as PropType<IVocals>,
			default: "",
		},
	},
	setup(props, { emit }) {
		const subject = props.subject || "pan-flute";
		const data = reactive({
			subject: subject,
			realKey: 0,
			notes: [] as IFIGNER_INSTRUMENT_Note[],
			soundFonts: {} as any,
			viewIndex: 0,
		});
		const fingerData = reactive({
			relationshipIndex: 0,
			subject: null as unknown as ITypeFingering,
			fingeringInfo: subjectFingering(data.subject),
		});
		const getNotes = () => {
			const fignerData = FIGNER_INSTRUMENT_DATA[data.subject as keyof typeof FIGNER_INSTRUMENT_DATA];
			if (fignerData) {
				data.notes = fignerData.list;
			}
		};
		const getFingeringData = async () => {
			const subject: any = data.subject + (data.viewIndex === 0 ? "" : data.viewIndex);
			fingerData.subject = await getFingeringConfig(subject);
		};
		const getSounFonts = () => {
			const pathname = /(192|localhost)/.test(location.origin) ? "/" : location.pathname;
			for (let i = 0; i < data.notes.length; i++) {
				const note = data.notes[i];
				// console.log("🚀 ~ note:", i)
				let url = `${pathname}soundfonts/${data.subject}/`;
				url += note.realName;
				url += ".mp3";
				const noteAudio = new Howl({
					src: url,
					loop: true,
				});
				data.soundFonts[note.realKey] = noteAudio;
			}
			// console.log("🚀 ~ data.soundFonts:", data.soundFonts);
		};
		onBeforeMount(() => {
			getNotes();
			getFingeringData();
			getSounFonts();
		});

		const noteClick = (item: IFIGNER_INSTRUMENT_Note, type: "start" | "stop") => {
			// console.log("🚀 ~ item:", item);
			const noteAudio = data.soundFonts[item.realKey];
			if (type === "start") {
				data.realKey = item.realKey;
				if (noteAudio) {
					noteAudio.play();
				}
			} else {
				data.realKey = 0;
				if (noteAudio) {
					noteAudio.stop();
				}
			}
		};

		/** 返回 */
		const handleBack = () => {
			if (props.isComponent) {
				console.log("关闭");
				emit("close");
				return;
			}
			// 不在APP中,
			if (!storeData.isApp) {
				window.close();
				return;
			}
			api_back();
		};

		return () => {
			const relationship = fingerData.subject?.relationship?.[data.realKey] || [];
			const rs: number[] = Array.isArray(relationship[1])
				? relationship[fingerData.relationshipIndex]
				: relationship;
			const canTizhi = Array.isArray(relationship[1]);
			return (
				<div class={styles.fingerBox}>
					<div class={styles.head}>
						<div class={styles.left}>
							<button
								class={[styles.backBtn, data.subject === "pan-flute" && styles.backRight]}
								onClick={() => handleBack()}
							>
								<img src={icons.icon_back} />
							</button>
							{data.subject === "pan-flute" && (
								<div
									class={styles.baseBtn}
									onClick={() => {
										data.viewIndex++;
										if (data.viewIndex > 1) {
											data.viewIndex = 0;
										}
										getFingeringData();
									}}
								>
									切换视图
								</div>
							)}
						</div>
						<div class={styles.rightBtn}>
							<div class={[styles.item, styles.disabled]}>
								<img src={icons.icon_2_0} />
								<span>还原</span>
							</div>
							<div class={[styles.item, styles.disabled]}>
								<img src={icons.icon_2_1} />
								<span>小技巧</span>
							</div>
						</div>
					</div>
					<div class={styles.fingerContent}>
						<div class={[styles.fingeringContainer]}>
							<div class={styles.imgs}>
								<img src={fingerData.subject?.json?.full} />
								{rs.map((key: number | string, index: number) => {
									const nk: string = typeof key === "string" ? key.replace("active-", "") : String(key);
									return <img data-index={nk} src={fingerData.subject?.json?.[nk]} />;
								})}
							</div>

							<div
								class={[styles.tizhi, canTizhi && styles.canDisplay]}
								onClick={() =>
									(fingerData.relationshipIndex = fingerData.relationshipIndex === 0 ? 1 : 0)
								}
							>
								替指
							</div>
						</div>
					</div>
					<div class={styles.notes}>
						{/* <Button>
							<Icon name="arrow-left" />
						</Button> */}
						<div class={styles.noteBox}>
							{data.notes.map((note: IFIGNER_INSTRUMENT_Note) => {
								const steps = new Array(Math.abs(note.step)).fill(1);
								return (
									<div
										draggable={false}
										class={styles.note}
										onKeydown={() => noteClick(note, "start")}
										onKeyup={() => noteClick(note, "start")}
										onMouseleave={() => noteClick(note, "stop")}
										onTouchstart={() => noteClick(note, "start")}
										onTouchend={() => noteClick(note, "stop")}
										onTouchcancel={() => noteClick(note, "stop")}
									>
										{data.realKey === note.realKey ? (
											<img draggable={false} src={icons.icon_btn_ylow} />
										) : (
											<img draggable={false} src={icons.icon_btn_blue} />
										)}

										<div class={[styles.noteKey, data.realKey === note.realKey && styles.keyActive]}>
											{note.step > 0 ? steps.map((n) => <span class={styles.dot}></span>) : null}

											<div class={styles.noteName}>
												<sup>
													{note.mark && (note.mark === "rise" ? "#" : "b")}
												</sup>
												{note.key}
											</div>
											{note.step < 0 ? steps.map((n) => <span class={styles.dot}></span>) : null}
										</div>
									</div>
								);
							})}
						</div>
						{/* <Button size="small" >
							<Icon name="arrow" />
						</Button> */}
					</div>
				</div>
			);
		};
	},
});
