import useXComponentConfig from "./use-x-component-config.js";
import { KeyCode } from "@v-c/util";
import { computed, onBeforeUnmount, ref, shallowRef, unref, watch } from "vue";
//#region components/_utils/hooks/use-shortcut-keys.ts
var PrefixKeys = {
	Alt: [
		"altKey",
		"Alt",
		"Alt"
	],
	Ctrl: [
		"ctrlKey",
		"Ctrl",
		"Ctrl"
	],
	Meta: [
		"metaKey",
		"Cmd",
		"Win"
	],
	Shift: [
		"shiftKey",
		"Shift",
		"Shift"
	]
};
var NumberKeyCode = Array.from({ length: 9 }, (_, i) => KeyCode.ONE + i);
var isAppleDevice = /(mac|iphone|ipod|ipad)/i.test(typeof navigator !== "undefined" ? navigator?.platform : "");
var KeyCodeNameMap = {
	[KeyCode.BACKSPACE]: "Backspace",
	[KeyCode.TAB]: "Tab",
	[KeyCode.ENTER]: "Enter",
	[KeyCode.ESC]: "Esc",
	[KeyCode.SPACE]: "Space",
	[KeyCode.DELETE]: "Delete"
};
var getShortcutKeysIcon = (key) => {
	if (key === "number") return key;
	if (typeof key === "string" && PrefixKeys?.[key]?.[isAppleDevice ? 1 : 2]) return PrefixKeys[key][isAppleDevice ? 1 : 2];
	if (typeof key === "number") {
		if (key >= KeyCode.A && key <= KeyCode.Z) return String.fromCharCode(key);
		if (key >= KeyCode.ZERO && key <= KeyCode.NINE) return String.fromCharCode(key);
		return KeyCodeNameMap[key] ?? "";
	}
	return "";
};
function getShortcutAction(shortcutKey, event) {
	const copyShortcutKey = [...shortcutKey];
	const keyCode = copyShortcutKey.pop();
	if (!copyShortcutKey.reduce((value, signKey) => {
		if (!value) return value;
		return event[PrefixKeys?.[signKey]?.[0]] || false;
	}, keyCode === event.keyCode)) return false;
	return {
		actionShortcutKey: shortcutKey,
		actionKeyCodeNumber: NumberKeyCode.indexOf(event.keyCode) > -1 ? NumberKeyCode.indexOf(event.keyCode) : false,
		actionKeyCode: event.keyCode,
		timeStamp: event.timeStamp
	};
}
function getDecomposedShortcutKeys(shortcutKeys) {
	const copyShortcutKey = [...shortcutKeys];
	const keyCode = copyShortcutKey.pop();
	return {
		keyCodeDict: keyCode === "number" ? NumberKeyCode : [keyCode],
		prefixKeys: copyShortcutKey
	};
}
function getFlattenShortcutKeys(contextShortcutKeys, componentShortcutKeys) {
	const mergeShortcutKeys = Object.assign({}, contextShortcutKeys || {}, componentShortcutKeys);
	return Object.keys(mergeShortcutKeys).reduce(({ flattenShortcutKeys, shortcutKeysInfo }, subName) => {
		const subShortcutKeys = mergeShortcutKeys[subName];
		if (!Array.isArray(subShortcutKeys)) return {
			flattenShortcutKeys,
			shortcutKeysInfo
		};
		const subShortcutInfo = {
			shortcutKeys: subShortcutKeys,
			shortcutKeysIcon: []
		};
		shortcutKeysInfo = {
			...shortcutKeysInfo,
			[subName]: subShortcutInfo
		};
		if (subShortcutKeys.every((item) => Array.isArray(item))) subShortcutKeys.forEach((shortcutKey, index) => {
			const shortcutKeyArr = shortcutKey;
			flattenShortcutKeys.push({
				name: subName,
				shortcutKey: shortcutKeyArr,
				index
			});
			subShortcutInfo.shortcutKeysIcon.push(shortcutKeyArr.map((key) => getShortcutKeysIcon(key)));
		});
		else {
			const { keyCodeDict, prefixKeys } = getDecomposedShortcutKeys(subShortcutKeys);
			keyCodeDict.forEach((keyCode) => {
				flattenShortcutKeys.push({
					name: subName,
					shortcutKey: [...prefixKeys, keyCode]
				});
			});
			subShortcutInfo.shortcutKeysIcon = subShortcutKeys.map((key) => getShortcutKeysIcon(key));
		}
		return {
			flattenShortcutKeys,
			shortcutKeysInfo
		};
	}, {
		flattenShortcutKeys: [],
		shortcutKeysInfo: {}
	});
}
function useShortcutKeys(component, shortcutKeys, options) {
	const contextConfig = useXComponentConfig(component);
	const shortcutAction = ref(null);
	const observer = shallowRef();
	const keyLockRef = ref(false);
	const flattenShortcutResult = computed(() => getFlattenShortcutKeys(contextConfig.value.shortcutKeys ?? {}, unref(shortcutKeys)));
	const shortcutKeysInfo = computed(() => flattenShortcutResult.value.shortcutKeysInfo);
	const subscribe = (fn) => {
		observer.value = fn;
	};
	const onKeydown = (event) => {
		if (keyLockRef.value || options?.shouldIgnore?.(event)) return;
		for (const shortcutKeyInfo of flattenShortcutResult.value.flattenShortcutKeys) {
			const activeKeyInfo = getShortcutAction(shortcutKeyInfo.shortcutKey, event);
			if (!activeKeyInfo) continue;
			const info = {
				...activeKeyInfo,
				name: shortcutKeyInfo.name,
				index: shortcutKeyInfo.index
			};
			keyLockRef.value = true;
			shortcutAction.value = info;
			observer.value?.(info);
			return;
		}
	};
	const onKeyup = () => {
		keyLockRef.value = false;
	};
	watch(() => flattenShortcutResult.value.flattenShortcutKeys.length, (length) => {
		if (typeof document === "undefined") return;
		document.removeEventListener("keydown", onKeydown);
		document.removeEventListener("keyup", onKeyup);
		if (length > 0) {
			document.addEventListener("keydown", onKeydown);
			document.addEventListener("keyup", onKeyup);
		}
	}, { immediate: true });
	onBeforeUnmount(() => {
		if (typeof document === "undefined") return;
		document.removeEventListener("keydown", onKeydown);
		document.removeEventListener("keyup", onKeyup);
	});
	return [
		shortcutAction,
		shortcutKeysInfo,
		subscribe
	];
}
//#endregion
export { useShortcutKeys as default, getShortcutKeysIcon };
