<template>
  <div class="sy-select" v-outside="handleOutside">
    <input type="text"
           @keydown.up.prevent="heightLight(heightLightIndex-1)"
           @keydown.down.prevent="heightLight(heightLightIndex+1)"
           @keydown.enter="handleKeyEnter"
           @change="handleChange"
           @focus="handleFocus"
           v-model="value"
           ref="input"
    >
    <transition name="fade">
      <div ref="listWrap" class="list-wrap" v-show="showSuggestion">
        <i class="el-icon-loading" v-show="loading">加载中 ... </i>
        <ul class="select-list" v-if="suggestions.length">
          <li
            v-for="(item , index) in suggestions"
            :class="{'isActive':heightLightIndex===index}"
            @click="handleClickSuggestion(index)"
            :key="item.value"
          >
            {{item.value}}
          </li>
        </ul>
        <div class="no-data-text" v-show="!loading" v-else>{{noDataText}}</div>
      </div>
    </transition>
  </div>
</template>
<script>
import clickOutside from '../utils/directives/clickOutside';

export default {
  name: 'SySelect',
  data() {
    return {
      showSuggestion: false,
      heightLightIndex: -1,
      suggestions: [],
      loading: false,
      value: '',
    };
  },
  props: {
    fetchSuggestions: Function,
    noDataText: {
      type: String,
      default: '无数据',
    },
  },
  directives: {
    outside: clickOutside,
  },
  methods: {
    fetchData() {
      const searchStr = this.value;
      const vm = this;
      this.fetchSuggestions(searchStr, (suggestions) => {
        vm.loading = false;
        if (Array.isArray(suggestions)) {
          vm.suggestions = suggestions;
        } else {
          // eslint-disabled-next-line no-empty
        }
      });
    },
    heightLight(index) {
      if (!this.showSuggestion) return;

      if (index < 0) index = 0;
      if (index >= this.suggestions.length) {
        index = this.suggestions.length - 1;
      }
      this.heightLightIndex = index;
    },
    handleKeyEnter() {
      if (this.showSuggestion && this.heightLightIndex > -1) {
        this.loading = false;
        const selectItem = this.suggestions[this.heightLightIndex];
        this.select(selectItem);
      } else {
        this.suggestions = [];
        this.showSuggestion = true;
        this.loading = true;
        this.fetchData();
      }
    },
    handleClickSuggestion(index) {
      const selectItem = this.suggestions[index];
      this.heightLight(index);
      this.select(selectItem);
    },
    select(item) {
      this.value = item.value;
      this.suggestions = [];
      this.heightLightIndex = -1;
      this.showSuggestion = false;
      this.$refs.input.focus();
      this.$emit('select', item);
      this.$emit('input', item);
    },
    handleChange(/* str */) {
    },
    handleOutside() {
      this.showSuggestion = false;
    },
    handleFocus(e) {
      const inputWith = `${e.target.offsetWidth}px`;
      this.$refs.listWrap.style.width = inputWith;
    },
  },
};
</script>
<style lang="less">
  .isActive {
    background: #0082e6;
  }

  .sy-select {
    position: relative;

    input {
      width: 200px;
      height: 24px;
      margin: 0;
      padding: 0 4px;
      font-size: 15px;
    }

    .list-wrap {
      position: absolute;
      background-color: #fff;
      z-index: 2017;
      border: 1px solid #ddd;
      border-top: 0;
    }

    ul {
      max-height: 220px;
      overflow: hidden;
      overflow-y: auto;
    }

    li, ul {
      margin: 0;
      list-style: none;
      padding: 0;
      text-align: center;
    }

    li, .no-data-text {
      cursor: pointer;
      list-style: none;
      line-height: 36px;
      padding: 0 10px;
      margin: 0;
      color: #48576a;
      font-size: 14px;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;

      &:hover {
        background: lightblue;
      }
    }
  }
</style>
