<template>
  <!-- 联想组件 -->
  <div class="association-container" ref="association">
    <el-input
      class="association-input"
      :value="value"
      :placeholder="placeholder"
      :suffix-icon="suffixIcon"
      :clearable="clearable"
      @focus="preSearch.focus = true"
      @blur="onBlur"
      @input="onInput"
    ></el-input>
    <div
      class="pre-search-list"
      :style="{ top: preSearch.top + 'px' }"
      v-show="preSearchListShow"
      @mouseout="preSearch.hover = false"
      @mouseover="preSearch.hover = true"
    >
      <div
        class="pre-search-item ellipsis"
        v-for="(item, index) in preSearch.list"
        :key="index"
        @click="selectSearchItem(item)"
      >
        {{ item.value }}
      </div>
    </div>
  </div>
</template>

<script>
import { Input } from 'element-ui'
import { debounce } from 'lodash'

export default {
  name: 'AssociationInput',
  components: {
    [Input.name]: Input
  },
  props: {
    value: {
      type: String,
      default: ''
    },
    // 是否立即触发一次联想
    immediateAssociation: {
      type: Boolean,
      default: false
    },
    fetchAsync: {
      type: Function
    },
    clearable: {
      type: Boolean,
      default: false
    },
    suffixIcon: {
      type: String,
      default: 'el-icon-search'
    },
    placeholder: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      preSearch: {
        top: 0,
        hover: false,
        focus: false,
        list: []
      }
    }
  },
  computed: {
    preSearchListShow() {
      return (
        this.value.trim().length >= 2 &&
        this.preSearch.list.length &&
        (this.preSearch.focus || this.preSearch.hover)
      )
    }
  },
  created() {
    if (this.immediateAssociation) {
      this.preSearchList()
    }
  },
  mounted() {
    this.calcPreSearchTop()
  },
  methods: {
    calcPreSearchTop() {
      const { association } = this.$refs
      this.preSearch.top = association.clientHeight + 2
    },
    onInput(e) {
      this.$emit('input', e)
      this.preSearchList(e)
    },
    onBlur(e) {
      this.$emit('blur', e)
      this.$nextTick(() => {
        this.preSearch.focus = false
      })
    },
    preSearchList: debounce(async function (e) {
      const params = {
        value: this.value
      }
      if (params.value.length < 2) return

      let list = []
      if (this.fetchAsync) {
        try {
          const cbArr = await this.fetchAsync(params)
          if (Array.isArray(cbArr)) {
            list = cbArr
          }
        } catch (error) {
          console.log(error)
        }
      }
      this.preSearch.list = list
    }, 300),
    selectSearchItem(item) {
      this.$emit('select', item)
      // 选择后马上关闭备选列表
      this.$nextTick(() => {
        this.preSearch.focus = false
        this.preSearch.hover = false
      })
    }
  }
}
</script>

<style lang="scss" scoped>
::v-deep {
  .el-input__inner {
    width: 326px;
    height: 30px;
    line-height: 30px;
    border-color: #e0e0e0;
  }
  .el-input__icon {
    line-height: 30px;
  }
}
.association-container {
  position: relative;
  display: inline-block;
}
.pre-search-list {
  padding: 10px 0;
  position: absolute;
  z-index: 6;
  width: 100%;
  background: #fff;
  box-shadow: 0 0 10px rgb(0, 0, 0, 0.1);
  border-radius: 4px;
  overflow: hidden;
}
.pre-search-item {
  padding: 0 20px;
  width: 100%;
  font-size: 14px;
  line-height: 34px;
  color: #606266;
  box-sizing: border-box;
  transition: all 0.3s;
  cursor: pointer;
}
.pre-search-item:hover {
  color: #1d1d1d;
  background-color: #ececec;
}
</style>
