<template>
  <div ref="focusElement">
    <FormWrapper
      class="input-select select-component select-wrapper"
      v-bind="formProps"
    >
      <div
        class="input-wrapper"
        @click="setActive(true)"
        @focus="setActive(true)"
        tabindex="1"
      >
        <input
          class="h600"
          ref="input"
          :class="{ error: props.error, disabled: props.disabled, active }"
          type="text"
          :placeholder="props.placeholder"
          @focus="setActive(true)"
          @input="changeHandler"
          @accept="onAccept"
          v-mask-directive="props.mask"
        />
      </div>

      <AccordionSheet :active="active" @close="setActive(false)">
        <ul class="main h600" v-show="active">
          <li
            v-for="(item, index) in list"
            :key="index"
            :class="{ selected: state.currentValue === item.title }"
            @click="selectItem(index)"
          >
            <div class="item">
              <span>{{ item.title }}</span>
            </div>
          </li>
        </ul>
      </AccordionSheet>
    </FormWrapper>
  </div>
</template>

<script lang="ts">
import { defineComponent, PropType, reactive, ref, watch } from "vue";
import { SelectInterface } from "@/models";
import { MaskDirective } from "@/directives/mask-directive";
import FormMixin from "@/mixins/FormMixin";
import { useFocusOut } from "@/hooks";
export default defineComponent({
  mixins: [FormMixin],
  directives: { MaskDirective },
  props: {
    list: {
      type: Array as PropType<SelectInterface[]>,
      default: [],
    },
    mask: {},
    formatted: {
      type: Boolean,
      default: false,
    },
    modelValue: {
      default: "",
    },
  },
  setup(props: any, { emit }) {
    const { focusOutElement, active, focusElement } = useFocusOut();
    focusOutElement.value = ".input-container";

    const input = ref(null);
    const state = reactive<{
      selectedId: number | null;
      currentValue: string | null;
    }>({
      selectedId: null,
      currentValue: null,
    });

    const ocusOutCallback = () => {
      setActive(false);
    };

    const selectItem = (index: number): void => {
      state.currentValue = props.list[index].title;
      (input.value as HTMLInputElement).value = state.currentValue;
      setActive(false);
    };

    const setActive = (ac: boolean): void => {
      if (props.disabled) {
        active.value = false;
        return;
      }
      active.value = ac;
    };

    const onAccept = (event: any): void => {
      state.currentValue = props.formatted
        ? event.detail.value
        : event.detail.unmasked;
      emit("update:modelValue", state.currentValue);
    };

    const changeHandler = (event: any): void => {
      if (props.mask) {
        state.currentValue = event.target.value;
      }
    };

    watch(
      (): string | null => state.currentValue,
      (newVal: string | null): void => {
        emit("update:modelValue", newVal);
      }
    );

    return {
      active,
      focusElement,
      ocusOutCallback,
      onAccept,
      setActive,
      changeHandler,
      state,
      selectItem,
      props,
      input,
    };
  },
});
</script>

<style lang="scss">
.input-select {
  &.disabled {
    pointer-events: none;

    input {
      pointer-events: none !important;
    }
  }

  input {
    width: 100%;
    height: var(--height);
    background: var(--background);
    padding: 0 var(--form-side-padding);
    border: 1px solid var(--border-color);
    border-radius: var(--form-border-radius);
    box-shadow: var(--box-shadow);
    transition: box-shadow 0.3s ease, border 0.3s ease;
    pointer-events: none;

    &.disabled {
      cursor: default;
    }

    &.active {
      border-color: var(--blue);
      box-shadow: 0 4px 10px var(--blue-10);
    }
  }

  .input-wrapper {
    outline: none;
  }

  .accordion-sheet {
    --scroll-max-height: 270px;
    --scroll-min-height: 0px;
  }

  @include screen-md() {
    --list-item-margin: 0;

    input {
      pointer-events: initial;
    }
  }
}
</style>
