<template>
  <el-popper ref="popperMain" :visible="visible" placement="bottom-left" @keydown.down.prevent="handleDownChoose" @keyup.enter.prevent="handleEnter" @keydown.up.prevent="handleUpChoose" :class="{'fbg-select': true}" @click="handleSelectClick">
    <div @mouseenter="isOverInput = true" @mouseleave="isOverInput = false" style="height: 100%">
      <input ref="mainRef" @keyup.enter="handleSelectEnter" v-model="text" :class="{'fbg-form-item-status': true, 'fbg-select-text': true, 'fbg-select-disabled': disabled}" :disabled="disabled" @click="handleClick" :placeholder="placeholder" readonly />
      <i v-show="isShowRemoveButton&&clearable" @click="handleRemove" class="fbg-icon-close fbg-select-icon" />
      <i v-show ="!(isShowRemoveButton&&clearable)" class="fbgiconfont icon-jiantouxia fbg-select-icon" />
    </div>
    <div slot="popup">
      <div ref="selectUlRef" style="padding: 5px 0px">
        <div class="fbg-select-box-search" v-if="filterable">
          <div :class="{'select-comp-sdh': multiple}">
            <el-input :value="keyword" ref="searchRef" icon="search" @click.stop @input="handleSearch" style="width: 100%;" clearable :check="false" :placeholder="searchPlaceholder"/>
          </div>
          <span v-if="multiple" @click="handleSelectAll" class="select-muti-btn">全选</span>
        </div>
        <ul v-if="$slots.default" style="max-height: 350px;overflow-y:auto">
          <slot/>
        </ul>
        <div class="fbg-select-no-data" v-if="!($slots.default && $slots.default.length)">
          <slot name="noData">{{noDataText}}</slot>
        </div>
        <div class="fbg-select-no-data" v-else-if="isEmptyMatch">
          <slot name="noMatch">{{noMatchText}}</slot>
        </div>
      </div>
    </div>
  </el-popper>
</template>
<script>
import Input from '../input';
import util from '../../utils';
import { setTimeout, clearTimeout } from 'timers';
import extendData from '../common/commonExtend';
import Popper from '../popper/index.vue';
window.time = 0;
export default {
  name: 'FbgSelect',
  componentName: 'FbgSelect',
  extends: extendData,
  components: {
    'el-input': Input,
    'el-popper': Popper
  },
  props: {
    noDataText: {
      type: String,
      default: '暂无数据'
    },
    noMatchText: {
      type: String,
      default: '无匹配数据'
    },
    //  搜索内容大小写敏感
    isSensitive: {
      type: Boolean,
      default: false
    },
    size: {
      type: String,
      default: 'md'
    },
    disabled: {
      type: Boolean,
      default: false
    },
    filterable: {
      type: Boolean,
      default: false
    },
    icon: {
      type: String,
      default: ''
    },
    clearable: {
      type: Boolean,
      default: true
    },
    placeholder: {
      type: String,
      default: ''
    },
    searchPlaceholder: {
      type: String,
      default: ''
    },
    value: {
      type: [String, Number, Array],
      default() {
        if (this.multiple) {
          return []
        } else {
          return '';
        }
      }
    },
    type: {
      type: String,
      default: 'text'
    },
    autosize: {
      type: Boolean,
      default: false
    },
    multiple: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    isEmptyMatch() {
      const res = this.options.filter(item => item.isShow);
      return !(res && res.length);
    },
    isShowRemoveButton() {
      return this.value !== '' && this.value !== null && this.isOverInput && !this.disabled;
    }
  },
  data() {
    return {
      visible: false,
      isOverInput: false,
      selectedItem: {},
      height: 0 + 'px',
      text: '',
      timer: null,
      addTimer: null,
      openStatus: false,
      keyword: '',
      options: [],
      count: 1,
      hoverIndex: 0,
      tabindex: 0
    };
  },
  created() {
    this.$on('fbg.select.addOption', (option) => {
      this.$refs.popperMain && this.$refs.popperMain.updatePositoin();
      option.index = this.count++;
      this.options.push(option);
      this.setCheckedOption(option);
      if (this.addTimer === null) {
        this.addTimer = setTimeout(() => {
          this.createText();
          clearTimeout(this.addTimer);
          this.addTimer = null;
        }, 20);
      }
      option.multiple = this.multiple;
      this.setShowOption(option);
    });
    this.$on('fbg.select.optionChange', (option) => {
      this.setValue(option);
      this.changeEmit(option.value);
      this.dispatch('FbgFormItem', 'fbg.formItem.validate', [this]);
      this.createText();
    });
    this.$on('fbg.select.mouseover', (option) => {
      this.hoverIndex = option.index;
    })
    this.$on('fbg.select.removeOption', (option) => {
      const index = this.options.indexOf(option);
      if (index > -1) {
        this.options.splice(index, 1);
      }
    });
  },
  watch: {
    keyword: {
      immediate: true,
      handler(value) {

      }
    },
    value: {
      immediate: true,
      deep: true,
      handler() {
        this.setCheckedOptionList();
        this.createText();
      }
    },
    visible: {
      handler(value) {
        if (value === false) {
          this.keyword = '';
          this.setShowOptionList();
        }
      }
    },
    multiple: {
      immediate: true,
      handler() {
        this.rewriteOptionMultiple();
      }
    }
  },
  mounted() {
    document.addEventListener('click', ()=>{
      if (!this.openStatus) {
        this.visible = false;
      }
      this.openStatus = false;
    });
  },
  methods: {
    handleSelectAll(){
      let arr = this.options.map(i => i.value);
      this.$emit('input', arr);
    },
    handleSelectEnter() {
      this.$refs.mainRef.click();
    },
    // rewrite option list multiple prop
    rewriteOptionMultiple() {
      this.options.forEach(item => {
        item.multiple = this.multiple;
      });
    },
    // set option list show prop
    setShowOptionList() {
      this.options.forEach(item => {
        this.setShowOption(item);
      });
    },
    setShowOption(option) {
      let label = option.label;
      if (label === null || typeof label === 'undefined') {
        label = '';
      }
      if (this.isSensitive) {
        option.isShow = label.toString().indexOf(this.keyword) > -1;
      } else {
        option.isShow = label.toString().toUpperCase().indexOf(this.keyword.toUpperCase()) > -1;
      }
    },
    createText() {
      const textList = [];
      this.options.forEach(item => {
        if (item.checked) {
          textList.push(item.label);
        }
      });
      this.text = textList.join(';');
    },
    handleRemove() {
      if (this.multiple) {
        this.$emit('input', []);
        this.$emit('change', []);
      } else {
        this.$emit('input', '');
        this.$emit('change', '');
      }
      this.dispatch('FbgFormItem', 'fbg.formItem.validate', [this]);
    },
    handleSelectClick() {
      this.openStatus = true;
    },
    handleClick() {
      this.openStatus = true;
      let timer = setTimeout(()=>{
        this.$refs.searchRef && this.$refs.searchRef.focus();
        clearTimeout(timer);
        timer = null;
      }, 600);
      this.visible = !this.visible;
    },
    handleSearch(value) {
      this.keyword = value;
      this.setShowOptionList();
    }
  }
}
</script>
<style lang="scss" scoped>
$placeholderColor : #999;
.select-comp-sdh{
  position:relative;
  padding-right: 40px;
}
.select-muti-btn{
  position: absolute;
  top: 20px;
  right: 15px;
  cursor: pointer;
  color: #296CD7;
}
.fbg {
  &-select {
    color: #666;
    font-size:0px;
    position: relative;
    display: inline-block;
    width: 100%;
    height: 32px;
    vertical-align: middle;
    box-sizing: border-box;
    cursor: pointer;
    &-no-data {
      padding: 5px 10px;
      color: #999;
    }
    &-disabled {
      background-color: #F0F0F0;
      border: 1px solid #ccc;
      cursor:not-allowed;
      &:hover {
        border: 1px solid #ccc;
      }
    }
    &-icon {
      position: absolute;
      right: 10px;
      top: 10px;
      color: #999;
      font-size: 12px;
    }
    &-open {
      .fbg-select-text{
        border-radius: 5px 5px 0px 0px;
        border: 1px solid $themeColor;
      }

    }
    &-text {
      height: 100%;
      border: 1px solid #ccc;
      border-radius: 5px;
      padding: 5px 10px;
      box-sizing: border-box;
      width: 100%;
      outline: none;
      &:focus {
        border: 1px solid $themeColor;
      }
    }
    &-box {
      display: none;
      height: 0px;
      overflow: hidden;
      transition: height 0.3s;
      position: absolute;
      top: 100%;
      background-color: #fff;
      width: 100%;
      z-index: 99999;
      box-sizing: border-box;
      border: 1px solid $themeColor;
      border-top: 0px;
      border-radius: 0px 0px 3px 3px;
      &-search {
        padding: 10px;
      }
    }
  }

}
</style>