<template>
  <div ref="simpleKeyboardBoxRef" style="width: 100%" class="simple-keyboard-box">
    <div v-show="isShow" class="simple-keyboard" :class="keyboardClass"></div>
  </div>
</template>

<script setup lang="ts">
  import { SimpleKeyboard } from 'simple-keyboard';
  import 'simple-keyboard/build/css/index.css';

  defineProps({
    /** 键盘容器 */
    keyboardClass: { type: String, default: 'simple-keyboard' },
  });
  const emit = defineEmits<{
    (e: 'change', value: string, activeElement: HTMLInputElement | null): void;
    (e: 'keypress', value: string): void;
  }>();
  let keyboard: SimpleKeyboard | null = null;

  const isShow = ref(false);
  let activeElement: HTMLInputElement | null = null;

  // 检测是否为触屏设备
  const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;

  const simpleKeyboardBoxRef = useTemplateRef('simpleKeyboardBoxRef');
  document.addEventListener('click', (event) => {
    const parent = simpleKeyboardBoxRef.value;
    if (!parent) {
      return;
    }
    const target = event.target!;
    if (!parent.contains(target as Node)) {
      activeElement = document.activeElement?.tagName === 'INPUT' ? (document.activeElement as HTMLInputElement) : null;
    }

    if (document.activeElement?.tagName === 'INPUT' || parent.contains(target as Node)) {
      isShow.value = true;
    } else {
      isShow.value = false;
    }

    if (keyboard && activeElement && activeElement.value !== keyboard.getInput()) {
      keyboard.setInput(activeElement.value);
    }

    // 如果是触屏设备，设置输入框为只读以防止弹出虚拟键盘
    if (isTouchDevice && activeElement) {
      activeElement.setAttribute('readonly', 'true');
    }

    setTimeout(() => {
      activeElement && activeElement.focus();
    }, 0);
  });

  document.addEventListener('keydown', () => {
    setTimeout(() => {
      if (keyboard && activeElement && activeElement.value !== keyboard.getInput()) {
        keyboard.setInput(activeElement.value);
      }
    }, 10);
  });

  // 初始化键盘
  onMounted(() => {
    keyboard = new SimpleKeyboard({
      mergeDisplay: true,
      layoutName: 'default',
      layout: {
        default: [
          '1 2 3 4 5 6 7 8 9 0',
          'q w e r t y u i o p',
          'a s d f g h j k l',
          '{shift} z x c v b n m {backspace}',
          '{numbers} {symbols} {space-wide} {ent}',
        ],
        shift: [
          '1 2 3 4 5 6 7 8 9 0',
          'Q W E R T Y U I O P',
          'A S D F G H J K L',
          '{shift} Z X C V B N M {backspace}',
          '{numbers} {symbols} {space-wide} {ent}',
        ],
        numbers: [
          '1 2 3',
          '4 5 6',
          '7 8 9',
          '{abc-narrow-numbers} {symbols-narrow-numbers} {zero-wide-numbers} {dot-narrow-numbers} {backspace-narrow-numbers}',
        ],
        symbols: [
          '. ! @ # $ % ; " \'',
          '& * ( ) - + = ? ,',
          '^ [ ] { } | \\ / :',
          '~ ` < > _ " \' ° § ¥',
          '{abc-equal-numbers} {space-wide-symbols} {backspace-narrow-symbols}',
        ],
      },
      display: {
        '{ent}': 'return',
        '{escape}': 'esc ⎋',
        '{tab}': 'tab ⇥',
        '{backspace}': '⌫',
        '{capslock}': 'caps lock ⇪',
        '{shift}': '⇧',
        '{controlleft}': 'ctrl ⌃',
        '{controlright}': 'ctrl ⌃',
        '{altleft}': 'alt ⌥',
        '{altright}': 'alt ⌥',
        '{metaleft}': 'cmd ⌘',
        '{metaright}': 'cmd ⌘',
        '{abc}': 'ABC',
        '{symbols}': '符号',
        '{zero}': '0',
        '{numbers}': '123',
        '{space-wide}': ' ',
        '{abc-equal-numbers}': 'ABC',
        '{space-wide-symbols}': ' ',
        '{backspace-narrow-symbols}': '⌫',
        '{abc-narrow-numbers}': 'ABC',
        '{symbols-narrow-numbers}': '符号',
        '{zero-wide-numbers}': '0',
        '{dot-narrow-numbers}': '.',
        '{backspace-narrow-numbers}': '⌫',
      },
      onChange: (input) => {
        emit('change', input, activeElement);
        if (activeElement) {
          activeElement.value = input;
        }
      },
      onKeyPress: (input) => {
        emit('keypress', input);

        // 创建字符输入处理函数
        const handleCharacterInput = (char: string) => {
          if (activeElement) {
            const currentValue = keyboard?.getInput() || '';
            const newValue = `${currentValue}${char}`;
            keyboard?.setInput(newValue);
            activeElement.value = newValue;
            emit('change', newValue, activeElement);
          }
        };

        // 创建退格处理函数
        const handleBackspace = () => {
          if (activeElement) {
            activeElement.value = activeElement.value.slice(0, -1);
            keyboard?.setInput(activeElement.value);
          }
        };

        // 大小写切换
        if (input === '{shift}' || input === '{lock}') {
          handleShift();
        }
        // ABC键处理（所有返回字母键盘的按钮）
        else if (['{abc}', '{abc-equal-numbers}', '{abc-narrow-numbers}'].includes(input)) {
          handleAbc();
        }
        // 符号键处理
        else if (['{symbols}', '{symbols-narrow-numbers}'].includes(input)) {
          handleSymbols();
        }
        // 数字键处理
        else if (input === '{numbers}') {
          handleNumbers();
        }
        // 空格键处理（所有空格键变体）
        else if (['{space-wide-symbols}', '{space-wide}'].includes(input)) {
          handleCharacterInput(' ');
        }
        // 退格键处理（所有退格键变体）
        else if (['{backspace-narrow-symbols}', '{backspace-narrow-numbers}', '{bksp}'].includes(input)) {
          handleBackspace();
        }
        // 0键处理（所有0键变体）
        else if (['{zero-wide-numbers}', '{zero}'].includes(input)) {
          handleCharacterInput('0');
        }
        // 小数点处理
        else if (input === '{dot-narrow-numbers}') {
          handleCharacterInput('.');
        }
      },
    });
  });

  /** 切换大小写 */
  function handleShift() {
    const currentLayout = keyboard!.options.layoutName;
    const shiftToggle = currentLayout === 'default' ? 'shift' : 'default';
    keyboard!.setOptions({
      layoutName: shiftToggle,
    });
  }

  /** 切换到数字键盘 */
  function handleNumbers() {
    keyboard!.setOptions({
      layoutName: 'numbers',
    });
  }

  /** 切换到字母键盘 */
  function handleAbc() {
    keyboard!.setOptions({
      layoutName: 'default',
    });
  }

  /** 切换到符号键盘 */
  function handleSymbols() {
    keyboard!.setOptions({
      layoutName: 'symbols',
    });
  }
</script>

<style lang="scss" scoped>
  html.dark .simple-keyboard-box :deep(.simple-keyboard) {
    background: var(--el-fill-color);

    .hg-button {
      background: var(--el-bg-color-page);
    }

    .hg-button:active {
      color: #ffffff;
      background: #04070a;
    }
  }

  // 只针对numbers键盘设置固定高度和行高度（使用特定的按键选择器来识别）
  .simple-keyboard-box :deep(.simple-keyboard:has([data-skbtn='{abc-narrow-numbers}'])) {
    min-height: 230px;
  }

  .simple-keyboard-box :deep(.simple-keyboard:has([data-skbtn='{abc-narrow-numbers}']) .hg-row) {
    min-height: 51px;
  }
  .simple-keyboard-box :deep(.simple-keyboard:has([data-skbtn='{abc-narrow-numbers}']) .hg-row .hg-button) {
    min-height: 51px;
  }
  .simple-keyboard-box :deep(.simple-keyboard .hg-button[data-skbtn='{zero}']) {
    flex-grow: 2;
    min-width: 120px;
  }

  .simple-keyboard-box :deep(.simple-keyboard .hg-button[data-skbtn='{numbers}']) {
    flex-grow: 0.6;
    max-width: 50px;
  }

  .simple-keyboard-box :deep(.simple-keyboard .hg-button[data-skbtn='{space-wide}']) {
    flex-grow: 3;
    min-width: 120px;
  }

  /* symbols键盘中{abc-equal-numbers}与{numbers}宽度相同 */
  .simple-keyboard-box :deep(.simple-keyboard .hg-button[data-skbtn='{abc-equal-numbers}']) {
    flex-grow: 0.6;
    max-width: 50px;
  }

  /* symbols键盘中调整space和backspace宽度 */
  .simple-keyboard-box :deep(.simple-keyboard .hg-button[data-skbtn='{space-wide-symbols}']) {
    flex-grow: 2.5;
    min-width: 100px;
  }

  .simple-keyboard-box :deep(.simple-keyboard .hg-button[data-skbtn='{backspace-narrow-symbols}']) {
    flex-grow: 0.8;
    max-width: 60px;
  }

  /* numbers键盘中0键占三分之一，其余4个按键平分三分之二 */
  .simple-keyboard-box :deep(.simple-keyboard .hg-button[data-skbtn='{zero-wide-numbers}']) {
    flex-grow: 1;
  }

  .simple-keyboard-box :deep(.simple-keyboard .hg-button[data-skbtn='{abc-narrow-numbers}']) {
    flex-grow: 0.5;
    max-width: 71px;
  }

  .simple-keyboard-box :deep(.simple-keyboard .hg-button[data-skbtn='{symbols-narrow-numbers}']) {
    flex-grow: 0.5;
    max-width: 71px;
  }

  .simple-keyboard-box :deep(.simple-keyboard .hg-button[data-skbtn='{dot-narrow-numbers}']) {
    flex-grow: 0.5;
    max-width: 71px;
  }

  .simple-keyboard-box :deep(.simple-keyboard .hg-button[data-skbtn='{backspace-narrow-numbers}']) {
    flex-grow: 0.5;
    max-width: 71px;
  }
</style>
