<template>
  <div
    ref="inputsRef"
    class="otp-inputs"
  >
    <div class="wrapper">
      <input
        class="h500"
        :class="{ disabled }"
        :id="`otp-input-${index}`"
        type="number"
        v-for="index of inputCount"
        @keydown="keyDownHandler($event, index - 1)"
        @input="inputHandler($event, index - 1)"
        :key="index"
        v-model="code[index - 1]"
        v-mask-directive="mask"
        @paste.prevent
        autocomplete="off"
      />
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, onMounted, computed } from "vue";
import { MaskDirective } from "@/directives/mask-directive";

export default defineComponent({
  emits: ['input'],
  directives: {
    MaskDirective
  },
  props: {
    inputCount: {
      type: Number,
      default: 4
    },
    disabled: {
      type: Boolean,
      default: false
    }
  },
  setup(_, { emit }) {
    const inputsRef = ref(null);
    const code = ref<number[]>([]);
    const mask = {
      mask: "num",
      blocks: {
        num: {
          mask: Number
        }
      }
    };

    const inputElements = computed(() => 
      inputsRef.value?.querySelectorAll("input") as NodeListOf<HTMLInputElement>
    );

    const inputHandler = (event: InputEvent, index: number) => {
      const inputData = parseInt(event.data);
  
      if (isNaN(inputData)) {
        return false;
      };

      if (!inputElements.value) return false;
  
      if (inputData >= 0 || inputData <= 9) {
        code.value[index] = inputData;
  
        const nextInput = inputElements.value[index + 1];
  
        if (nextInput) {
          nextInput.focus();
        } else {
          inputElements.value[index].blur();
        }
  
        emit("input", code.value.join(""));
      }
    };

    const keyDownHandler = async (event: KeyboardEvent, index: number) => {
      const target = event.target as HTMLInputElement;
  
      if (!inputElements.value) return false;
  
      if (
        event.key === "Backspace" ||
        event.key === "Delete" ||
        event.code === "Backspace" ||
        event.code === "Delete"
      ) {
        event.preventDefault();
        target.value = "";
        target.dispatchEvent(new CustomEvent("input"));
  
        if (index > 0) {
          inputElements.value[index - 1].focus();
        }
      }
  
      emit("input", code.value.join(""));
    }
    
    onMounted((): void => {
      const inputElement: HTMLInputElement = inputsRef.value.querySelector("input");
      inputElement.focus();
    });

    return {
      code,
      mask,
      inputsRef,
      keyDownHandler,
      inputHandler
    }
  }
});

// @Component({
// })
// export default class OTPInputs extends Vue {




// }
</script>

<style scoped lang="scss">
.otp-inputs {
  margin-bottom: 48px;

  .wrapper {
    display: flex;
    justify-content: center;
    align-items: center;

    input {
      width: 48px;
      padding: 8px 0;
      text-align: center;
      border-bottom: 1px solid var(--light-separator-opaque);
      transition: border 0.3s ease, background-color 0.2s ease;
      border-top-left-radius: 6px;
      border-top-right-radius: 6px;

      &:not(:last-child) {
        margin-right: 16px;
      }

      &:focus {
        border-bottom-color: var(--form-border-color-focus);
      }

      &.disabled {
        pointer-events: none;
      }
    }
  }

  @include screen-lg() {
    margin-bottom: 64px;

    .wrapper {
      input {
        width: 56px;

        &:not(:last-child) {
          margin-right: 24px;
        }
      }
    }
  }
}
</style>
