<template>
  <div
    ref="current"
    :class="[{
      [`mm-selector--${mode}`]: mode,
      'mm-selector--focused': visible || focused,
      'mm-selector--disabled': disabled,
      'mm-selector--clearable': clearable,
    }, themeClasses]"
    class="mm-selector"
    tabindex="0"
    @focusin="focusHandler"
    @focusout="blurHandler"
    @keydown="keydownHandler"
    @click="clickHandler">
    <template v-if="!(searchValue || isValidValue)">
      <slot name="placeholder"></slot>
    </template>
    <div class="mm-selector-rendered">
      <slot name="selection"></slot>
    </div>

    <span
      v-if="clearable && isValidValue"
      class="mm-selector__clear"
      @click.stop="clearHandler">
      <ui-icon
        name="clear"
        size="14px">
      </ui-icon>
    </span>

    <span
      v-if="showIcon"
      :class="[`mm-selector-suffix-icon`]">
      <slot name="suffix-icon">
        <ui-icon
          v-if="showArrow"
          :class="{
            [`mm-selector-arrow`]: true,
            [`mm-selector-arrow__reverse`]: visible,
          }"
          :style="{ outline: 'none' }"
          name="chevrondown"
          size="12px">
        </ui-icon>
      </slot>
    </span>
  </div>
</template>

<script>
import Icon from "../icon"
import themeSelect from "../../mixins/theme-select"

export default {
  name: "mm-selector-base",
  components: {
    "ui-icon": Icon,
  },
  mixins: [themeSelect],
  inheritAttrs: false,
  props: {
    visible: {
      type: Boolean,
    },
    value: {
      type: [Array, String, Number],
    },
    searchValue: {
      type: String,
    },
    placeholder: {
      type: String,
    },
    showArrow: {
      type: Boolean,
    },
    clearable: {
      type: Boolean,
    },
    onClick: {
      type: Function,
      default: () => {},
    },
    onBlur: {
      type: Function,
      default: () => {},
    },
    onFocus: {
      type: Function,
      default: () => {},
    },
    onKeydown: {
      type: Function,
      default: () => {},
    },
    onClear: {
      type: Function,
      default: () => {},
    },
    onSearchKeydown: {
      type: Function,
      default: () => {},
    },
    onSearchInput: {
      type: Function,
      default: () => {},
    },
    onSearchChange: {
      type: Function,
      default: () => {},
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    multiple: {
      type: Boolean,
    },
    filterable: {
      type: Boolean,
      default() {
        return this.multiple
      },
    },
    mode: {
      type: String,
    },

    hideOnBlur: {
      type: Boolean,
      default: true,
    },
    showIcon: {
      type: Boolean,
      default: true,
    },
  },

  data() {
    return {
      focused: false,
    }
  },
  computed: {
    isValidValue() {
      if (Array.isArray(this.value)) {
        return this.value.length
      }

      return !["", null, undefined].includes(this.value)
    },
  },
  methods: {
    focusHandler(event) {
      if (this.disabled) {
        return
      }

      this.clearBlurTime()
      this.clearFocusTime()

      if (!this.focused) {
        this.focusTimer = setTimeout(() => {
          this.focused = true

          if (this.onFocus) {
            this.onFocus(event)
          }
        }, 100)
      }
    },

    blurHandler(event) {
      if (this.disabled) {
        return
      }

      if (this.focused) {
        this.blurTimer = setTimeout(() => {
          this.focused = false
          this.$emit("blur", event)

          if (this.onBlur) {
            this.onBlur(event)
          }

          if (this.hideOnBlur) {
            this.$emit("update:visible", false)
            this.$emit("update:searchValue", "")
          }
        }, 100)
      }
    },

    clearBlurTime() {
      if (this.blurTimer) {
        clearTimeout(this.blurTimer)
        this.blurTimer = null
      }
    },

    clearFocusTime() {
      if (this.focusTimer) {
        clearTimeout(this.focusTimer)
        this.focusTimer = null
      }
    },

    focus() {
      this.$refs.current.focus()
    },

    blur() {
      this.$refs.current.focus()
    },
    keydownHandler(event) {
      this.onKeydown(event)
      this.$emit("keydown", event)
    },
    clearHandler(event) {
      this.onClear(event)
      this.$emit("clear", event)
    },
    clickHandler(event) {
      if (this.disabled) {
        return
      }

      this.onClick(event)
      this.$emit("click", event)
      this.$emit("update:visible", !this.visible)
    },
  },
}
</script>
