<script setup lang="ts">
import {
  JS_KEY_SHIFT,
  JS_KEY_CTRL,
  JS_KEY_ALT,
  JS_KEY_LWIN,
  JS_KEY_PRNT,
} from '@/pages/Service/Kvm/utils/keysCode';
import { reactive, ref } from 'vue';
import { ZoomOut, ZoomIn, Close, ArrowLeft, ArrowDown, ArrowRight, ArrowUp } from '@element-plus/icons-vue';
import { LAYOUT_US } from './language';
import { capsLockState } from '../classes/sharedStates';
interface keyProps {
  ctrlKey: boolean;
  shiftKey: boolean;
  altKey: boolean;
  metaKey: boolean;
}
const showNumberPad = ref<boolean>(true);
const scrollLock = ref(0);
const numLock = ref(0);
const keyBoardSize = ref(2);
const defaultLayout = reactive(LAYOUT_US);
const isShiftActive = ref(false);
const shiftLoaction = ref(1);
const isPSActive = ref(false);
const psLoaction = ref(1);
const isCtrlActive = ref(false);
const ctrlLoaction = ref(1);
const isAltActive = ref(false);
const altLoaction = ref(1);
const isMetaActive = ref(false);
const metaLoaction = ref(1);
const SP_KEYS = reactive([
  'Home',
  'ScrollLock',
  'PageUp',
  'PageDown',
  'End',
  'Delete',
  'Prnt Scrn',
  'Insert',
  'Enter',
]);
const emit = defineEmits(['close', 'click-bodard']);

const creatEvent = (key: string, code: string, keyCode: number, location: number, ...args: any) => {
  let obj: keyProps = {
    ctrlKey: false,
    shiftKey: false,
    altKey: false,
    metaKey: false,
  };
  Object.assign(obj, ...args);
  const { ctrlKey, shiftKey, altKey, metaKey } = obj;
  return new KeyboardEvent('keydown', {
    location,
    bubbles: true,
    cancelable: false,
    key,
    code,
    keyCode,
    ctrlKey,
    shiftKey,
    altKey,
    metaKey,
  });
};
// 左边键盘点击
const leftKeyClick = (obj: any) => {
  const { key, location, code, keyCode, stickiness } = obj;
  if (key === 'CapsLock') {
    capsLockState.value = !capsLockState.value;
  }
  if (keyCode === JS_KEY_SHIFT) {
    isShiftActive.value = !isShiftActive.value;
    shiftLoaction.value = location;
  }
  if (keyCode === JS_KEY_CTRL) {
    isCtrlActive.value = !isCtrlActive.value;
    ctrlLoaction.value = location;
  }
  if (keyCode === JS_KEY_ALT) {
    isAltActive.value = !isAltActive.value;
    altLoaction.value = location;
  }
  if (keyCode === JS_KEY_LWIN) {
    isMetaActive.value = !isMetaActive.value;
    metaLoaction.value = location;
  }
  if (keyCode === JS_KEY_PRNT) {
    isPSActive.value = !isPSActive.value;
    psLoaction.value = location;
  }
  let e = creatEvent(key, code, keyCode, location, {
    ctrlKey: key === 'Control',
    shiftKey: key === 'Shift',
    altKey: key === 'Alt',
    metaKey: key === 'Meta',
    psKey: key === 'Prnt Scrn',
  });
  e.getModifierState = (keyStr: string): boolean => {
    if (keyStr === 'CapsLock') {
      return capsLockState.value;
    } else if (keyStr === 'ScrollLock') {
      return scrollLock.value === 1 ? true : false;
    } else if (keyStr === 'NumLock') {
      return numLock.value === 1 ? true : false;
    } else {
      return capsLockState.value;
    }
  };
  emit('click-bodard', e, {
    stickiness,
    isShiftActive: isShiftActive.value,
    isAltActive: isAltActive.value,
    isCtrlActive: isCtrlActive.value,
    isMetaActive: isMetaActive.value,
    shiftLoaction: shiftLoaction.value,
    altLoaction: altLoaction.value,
    ctrlLoaction: ctrlLoaction.value,
    metaLoaction: metaLoaction.value,
    isPSActive: isPSActive.value,
    psLoaction: psLoaction.value,
  });
  resetKey(keyCode);
};
// 右边小键盘点击
const rightKeyClick = (obj: any) => {
  const { key, location, code, keyCode } = obj;
  if (key === 'ScrollLock') {
    scrollLock.value = scrollLock.value === 0 ? 1 : 0;
  }
  if (keyCode === JS_KEY_PRNT) {
    isPSActive.value = !isPSActive.value;
    psLoaction.value = location;
  }
  let e = creatEvent(key, code, keyCode, location, {
    psKey: key === 'Prnt Scrn',
  });
  e.getModifierState = (keyStr: string): boolean => {
    if (keyStr === 'CapsLock') {
      return capsLockState.value;
    } else if (keyStr === 'ScrollLock') {
      return scrollLock.value === 1 ? true : false;
    } else if (keyStr === 'NumLock') {
      return numLock.value === 1 ? true : false;
    } else {
      return capsLockState.value;
    }
  };
  emit('click-bodard', e, {
    stickiness: false,
    isShiftActive: isShiftActive.value,
    isAltActive: isAltActive.value,
    isCtrlActive: isCtrlActive.value,
    isMetaActive: isMetaActive.value,
    shiftLoaction: shiftLoaction.value,
    altLoaction: altLoaction.value,
    ctrlLoaction: ctrlLoaction.value,
    metaLoaction: metaLoaction.value,
    isPSActive: isPSActive.value,
    psLoaction: psLoaction.value,
  });
  resetKey(keyCode);
};
const resetKey = (keyCode: number) => {
  if (![0x10, 0x11, 0x12, JS_KEY_LWIN, 0x2c].includes(keyCode)) {
    isShiftActive.value = false;
    isAltActive.value = false;
    isCtrlActive.value = false;
    isMetaActive.value = false;
    isPSActive.value = false;
    shiftLoaction.value = 1;
    altLoaction.value = 1;
    ctrlLoaction.value = 1;
    metaLoaction.value = 1;
  }
};
// 开关小键盘
const toggleNumberPad = () => {
  showNumberPad.value = !showNumberPad.value;
};
// 关闭虚拟键盘
const close = () => {
  emit('close');
};
// 键盘拖拽
const vDomDrag = (el: HTMLElement) => {
  let oDiv: HTMLElement = el;
  oDiv.style.cssText += ';cursor: move;';
  let isDragging = false;
  const mouseDown = (e: MouseEvent) => {
    isDragging = true;
    let disX = e.clientX - oDiv.offsetLeft;
    let disY = e.clientY - oDiv.offsetTop;
    const move = (ev: MouseEvent) => {
      let l = ev.clientX - disX;
      let t = ev.clientY - disY;
      oDiv.style.left = `${l}px`;
      oDiv.style.top = `${t}px`;
    };
    document.addEventListener('mousemove', move);
    document.addEventListener('mouseup', () => {
      isDragging = false;
      document.removeEventListener('mousemove', move);
    });
  };
  oDiv.addEventListener('mousedown', mouseDown, false);
};

const getRealItem = (item: any) => {
  const idx = capsLockState.value ? 1 : 0;
  return item[idx];
};

</script>
<template>
  <div v-dom-drag class="keyboard">
    <table id="container" :class="['keyboard-size' + keyBoardSize]">
      <thead>
        <tr>
          <th colspan="2" class="header">
            <span
              id="numpadToggle"
              :title="
                !showNumberPad ? $t('SERVICE_WBS_CRE_SHOW_MORE') : $t('SERVICE_WBS_CRE_HIDE_MORE')
              "
              @click="toggleNumberPad"
            >
              <img src="@/assets/common/image/opener.svg" alt="" />
            </span>
            <strong :title="$t('CLOSE_VIRTUAL_kEYBOARD')" @click.stop="close">
              <el-icon :size="16"><Close /></el-icon>
            </strong>
          </th>
        </tr>
      </thead>
      <tbody>
        <tr class="body-tr">
          <td
            id="keyboardInputKeyboard"
            :class="{
              'hide-pad-num': !showNumberPad
            }"
          >
            <!-- 左边键盘 -->
            <table
              v-for="(item, idx) in defaultLayout.keys"
              :key="idx"
              :class="{ inputCenter: idx === defaultLayout.keys.length - 1 }"
            >
              <tbody>
                <tr>
                  <td
                    v-for="(itm, idx2) in item"
                    :key="idx2"
                    class="item"
                    :class="{
                      'w1 td-highlight': ['Esc', 'Tab'].includes(getRealItem(itm).showKey),
                      w2: ['F10', 'F11', 'F12'].includes(getRealItem(itm).showKey),
                      'w3 td-highlight': ['Bksp', 'Enter'].includes(getRealItem(itm).showKey),
                      'w4 td-highlight': ['Caps'].includes(getRealItem(itm).showKey),
                      'w5 td-highlight': getRealItem(itm).showKey === 'Shift',
                      w6: getRealItem(itm).showKey === 'Space',
                      'w7 td-highlight': getRealItem(itm).showKey === 'Win',
                      'w8 td-highlight': getRealItem(itm).showKey === 'Ctrl',
                      'w9 td-highlight': getRealItem(itm).showKey === 'Alt',
                      'shift-active': getRealItem(itm).showKey === 'Shift' && isShiftActive,
                      'ctrl-active': getRealItem(itm).showKey === 'Ctrl' && isCtrlActive,
                      'alt-active': getRealItem(itm).showKey === 'Alt' && isAltActive,
                      'win-active': getRealItem(itm).showKey === 'Win' && isMetaActive,
                      'caps-on': ['Caps'].includes(getRealItem(itm).showKey) && capsLockState,
                    }"
                    @click="
                      leftKeyClick({
                        key: getRealItem(itm).key,
                        location: getRealItem(itm).location,
                        code: defaultLayout.code[idx][idx2][capsLockState ? 1 : 0],
                        keyCode: defaultLayout.keyCode[idx][idx2][capsLockState ? 1 : 0],
                        stickiness: getRealItem(itm).stickiness
                      })
                    "
                  >
                      <template v-if="!isNaN(parseInt(itm[0].showKey, 10)) && !capsLockState">
                        <div class="num-key-container">
                          <span class="shift-modify">{{ itm[1].showKey }}</span>
                          <span class="no-modify">{{ itm[0].showKey }}</span>
                        </div>
                      </template>
                      <template v-else>
                        {{ getRealItem(itm).showKey || '\xa0' }}
                      </template>
                  </td>
                </tr>
              </tbody>
            </table>
          </td>
          <td
            id="inputNumpad"
            :class="{
              'hide-pad-num': !showNumberPad
            }"
          >
            <!-- 右边的小键盘 -->
            <template v-if="showNumberPad">
              <table
                v-for="(item, idx) in defaultLayout.smallKeys"
                :key="idx"
                border="0"
                cellspacing="0"
                cellpadding="0"
              >
                <tbody>
                  <tr>
                    <td
                      v-for="(itm, idx2) in item"
                      :key="idx2"
                      :class="{
                        'td-highlight': SP_KEYS.includes(itm[0].key),
                        'ps-active': (itm[0].showKey === 'Prnt Scrn' && isPSActive) ||
                          (itm[0].showKey === 'Scroll' && scrollLock),
                      }"
                      @click="
                        rightKeyClick({
                          key: itm[0].key,
                          location: itm[0].location || 0,
                          code: defaultLayout.smallCode[idx][idx2][0],
                          keyCode: defaultLayout.smallKeyCode[idx][idx2][0]
                        })
                      "
                    >
                      <el-icon v-if="itm[0].showKey === 'left'" id="arrowLeft">
                        <ArrowLeft />
                      </el-icon>
                      <el-icon v-else-if="itm[0].showKey === 'down'" id="arrowDown">
                        <ArrowDown />
                      </el-icon>
                      <el-icon v-else-if="itm[0].showKey === 'top'" id="arrowUp">
                        <ArrowUp />
                      </el-icon>
                      <el-icon v-else-if="itm[0].showKey === 'right'" id="arrowRight">
                        <ArrowRight />
                      </el-icon>
                      <template v-else>{{ itm[0].showKey }}</template>
                    </td>
                  </tr>
                </tbody>
              </table>
            </template>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</template>
<style scoped lang="scss">
@import './index.scss';
</style>
