/*
 *  ┌─────────────────────────────────────────────────────────────┐
 *  │┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐│
 *  ││Esc│!1 │@2 │#3 │$4 │%5 │^6 │&7 │*8 │(9 │)0 │_- │+= │|\ │`~ ││
 *  │├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┤│
 *  ││ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │{[ │}] │ BS  ││
 *  │├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤│
 *  ││ Ctrl │ A │ S │ D │ F │ G │ H │ J │ K │ L │: ;│" '│ Enter  ││
 *  │├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┤│
 *  ││ Shift  │ Z │ X │ C │ V │ B │ N │ M │< ,│> .│? /│Shift │Fn ││
 *  │└─────┬──┴┬──┴──┬┴───┴───┴───┴───┴───┴──┬┴───┴┬──┴┬─────┴───┘│
 *  │      │Fn │ Alt │         Space         │ Alt │Win│   HHKB   │
 *  │      └───┴─────┴───────────────────────┴─────┴───┘          │
 *  └─────────────────────────────────────────────────────────────┘
 */
import hotkeys from 'hotkeys-js';
import { throttle } from 'lodash-es';
import { useEffect, useMemo } from 'react';
import type { iHotKeyOption, tHotKeyCallBackType } from './hotkey.type';
// 默认配置项
const defaultOption: Required<iHotKeyOption> = {
  // 是否禁用此快捷键注册 默认为false 不禁用
  disabled: false,
  // 是否阻止浏览器的默认行为 默认为true 阻止默认事件
  stopDefaultEventEnabled: true,
  // 快捷键keys参数中的拆分字符 默认是使用 + 字符拆分
  splitKey: '+',
  // 执行间隔单位（ms） 默认200ms
  wait: 50,
  // 快捷键绑定元素
  element: null,
};

/**
 * @description: 清除默认事件
 * @param {KeyboardEvent} event
 * @return {void}
 */
const cleanDefaultEvent = (event: KeyboardEvent): void => {
  event.preventDefault();
  event.stopPropagation();
};

/**
 * @description: 快捷键基础HOOK
 * @param {tHotKeyCallBackType} callBack
 * @param {boolean} disabled
 * @return {React.MutableRefObject<Element | null>}
 */

const useBaseHotkey = (
  key: string,
  callBack: tHotKeyCallBackType,
  option?: iHotKeyOption,
) => {
  const finalOption = useMemo(() => {
    return {
      ...defaultOption,
      ...option,
    };
  }, [option]);

  const { splitKey, stopDefaultEventEnabled, disabled, wait, element } =
    finalOption;

  const hotHandle = throttle((event: KeyboardEvent) => {
    stopDefaultEventEnabled && cleanDefaultEvent(event);
    if (disabled) return;
    callBack && callBack(event);
  }, wait);

  useEffect(() => {
    hotkeys(key, { splitKey, element }, hotHandle);
    return () => {
      hotkeys.unbind(key, hotHandle);
    };
  }, [element, hotHandle, key, splitKey]);
};

export { useBaseHotkey };
