<template>
  <FormWrapper class="telephone-input" v-bind="props">
    <div class="wrapper" :class="{ focused }">
      <p class="code h600">{{ code }}</p>
      <i class="separator"></i>
      <div class="input-wrapper">
        <input
          class="h600"
          :placeholder="placeholder"
          v-focus-directive="focus"
          @focus="focused = true"
          @blur="focused = false"
          @keydown.enter="submit"
          type="tel"
          inputmode="decimal"
          ref="telephoneRef"
          :disabled="disabled"
        />
      </div>
      <div class="icon" v-if="hasIcon">
        <SpIcon name="sp-phone" />
      </div>
    </div>
  </FormWrapper>
</template>

<script lang="ts">
import {
  defineComponent,
  onBeforeUnmount,
  onMounted,
  reactive,
  ref,
  toRefs,
  watch,
} from "vue";
import IMask, { InputMask } from "imask";
import FormWrapper from "../FormWrapper.vue";
import FormMixin from "@/mixins/FormMixin";
import { DigitsDirective } from "@/directives/digits";
import { FocusDirective } from "@/directives/focus";

export default defineComponent({
  mixins: [FormMixin],
  emits: ["update:modelValue"],
  props: {
    modelValue: {
      type: [String],
      required: true,
    },
    code: {
      type: String,
      default: "+995",
    },
    maxLength: {
      type: Number,
    },
    hasIcon: {
      type: Boolean,
      default: true,
    },
    pattern: {
      type: String,
      default: "{5}00 00 00 00",
    },
  },
  components: {
    FormWrapper,
  },
  directives: {
    DigitsDirective,
    FocusDirective,
  },
  setup(props, { emit }) {
    const focused = ref(false);
    const currentValue = ref(null);
    const iMask = ref<InputMask<any>>();
    const refs = reactive<{
      telephoneRef: HTMLInputElement | null;
    }>({
      telephoneRef: null,
    });

    const setValue = (): void => {
      (iMask.value as any).value =
        props.modelValue === null || typeof props.modelValue === "undefined"
          ? ""
          : props.modelValue.toString();
      iMask.value?.updateValue();
    };

    watch(
      () => props.modelValue,
      (newValue) => {
        if (currentValue.value !== newValue) {
          setValue();
        }
      }
    );

    onMounted(() => {
      if (props.pattern) {
        const el = refs.telephoneRef as HTMLInputElement;
        iMask.value = IMask(el, {
          mask: "tel",
          blocks: {
            tel: {
              mask: props.pattern,
            },
          },
        });

        iMask.value.on("accept", () => {
          currentValue.value = iMask.value?.unmaskedValue as any;
          emit("update:modelValue", currentValue.value);
        });
      }

      if (props.modelValue) {
        setValue();
      }
    });

    onBeforeUnmount(() => {
      iMask.value?.destroy();
    });

    return {
      props,
      ...toRefs(refs),
      focused,
    };
  },
});
</script>

<style scoped lang="scss">
.telephone-input {
  .wrapper {
    width: 100%;
    display: flex;
    align-items: center;
    height: var(--height);
    background-color: var(--background);
    border: 1px solid var(--border-color);
    border-radius: var(--form-border-radius);
    padding: 0 0 0 var(--form-side-padding);
    pointer-events: var(--pointer-events);
    transition: var(--transition);

    &.focused {
      border-color: var(--form-border-color-active);
      box-shadow: var(--form-box-shadow);
    }

    .separator {
      height: 42.5%;
      width: 1px;
      background-color: var(--border-color);
      margin-left: calc(var(--form-side-padding) / 2);
    }

    .input-wrapper {
      flex-grow: 1;
      height: 100%;
    }

    input {
      padding-left: calc(var(--form-side-padding) / 2);
      border-bottom-right-radius: var(--form-border-radius);
      border-top-right-radius: var(--form-border-radius);
      height: 100%;
      width: 100%;

      &::placeholder {
        color: var(--form-placeholder-color);
      }
    }

    .icon {
      pointer-events: none;
      position: absolute;
      top: 50%;
      right: var(--form-side-padding);
      transform: translateY(-50%);
    }
  }
}
</style>
