<template>
  <div v-el:group class="btn-group" v-bind:class="{open: show, dropup: direction === 'up'}" :style="{width:width}">
    <button v-el:btn type="button" class="btn btn-default dropdown-toggle select-style" style="min-width: 100%;"
            :id="'vc-select-button-'+attach"
            @click="toggleDropdown"
            @blur="show = (search ? show : false)"
            v-bind="{disabled: disabled}"
    >
      <span class="btn-placeholder" v-show="showPlaceholder">{{ placeholder }}</span>
      <span class="btn-content" :style="{textOverflow:'ellipsis',overflow: 'hidden'}">{{ selectedItems }}</span>
      <span class="caret"></span>
    </button>
    <ul class="dropdown-menu" v-bind:class="{'menu-align-right': align=== 'right'}"
        :style="{overflow:'scroll',maxHeight: maxHeight + 'px',width:'auto',minWidth:minWidth,left:left+'px' }"
        v-el:dropdown>
      <template v-if="options.length">
        <li v-if="search" class="bs-searchbox" style="white-space: nowrap">
          <input type="text" placeholder="Search"
                 style="width: 80%;display: inline"
                 v-model="searchText"
                 class="form-control" autocomplete="off"
                 @keyup.enter="putOptions(searchText)">

          <span style="width: 20%;display: inline"
                v-if="search&&multiple&&show&&!isSelectAll"
                @mousedown.prevent="selectAll(options)">全选</span>
          <span style="width: 20%;display: inline"
                v-if="search&&multiple&&show&&isSelectAll"
                @mousedown.prevent="selectAll(options)">取消</span>
        </li>
        <li v-for="option in options | findBy searchText " style="position:relative">
          <a @mousedown.prevent="select(option.value,null)" style="cursor:pointer"
             :id="'vc-select-a-'+attach+'-'+$index">
            {{ option.label }}
            <span class="glyphicon glyphicon-ok check-mark" v-show="isSelected(option.value)"></span>
          </a>
        </li>
      </template>
      <slot v-else></slot>
      <div class="notify" v-show="showNotify" transition="fadein">Limit reached ({{ limit }} items max).
      </div>
    </ul>
  </div>
</template>

<script>
import EventListener from './utils/EventListener.js'
import coerceBoolean from './utils/coerceBoolean.js'

export default {
  props: {
    options: {
      type: Array,
      default() {
        return []
      },
    },
    value: {
      twoWay: true
    },
    placeholder: {
      type: String,
      default: '请选择'
    },
    multiple: {
      type: Boolean,
      coerce: coerceBoolean,
      default: false
    },
    search: { // Allow searching (only works when options are provided)
      type: Boolean,
      coerce: coerceBoolean,
      default: true
    },
    limit: {
      type: Number,
      default: 1024
    },
    closeOnSelect: { // only works when multiple==false
      type: Boolean,
      coerce: coerceBoolean,
      default: false
    },
    disabled: {
      type: Boolean,
      coerce: coerceBoolean,
      default: false
    },
    attach: {
      type: String,
      default: 'vuestrap'
    },
    enterPush: {
      type: Boolean,
      dafault: false
    },
    maxHeight: {
      type: [Number, String],
      default: 300
    },
    minWidth: {
      type: [Number, String],
      default: '100%'
    },
    valueSingle: {
      type: Boolean,
      default: false
    },
    //全选标志位
    isSelectAll: {
      type: Boolean,
      default: false
    },
    filerKey: {
      default: 'id'
    },
    direction: { // 展开方向，默认为向下，可以向上up
      type: String,
      default: 'down'
    },
    align: {
      type: String,
      default: 'left' // 内内容框对齐方式，默认是左对齐，也可以right，右对齐
    },
    width: {
      type: String,
      default: '60%'
    },
    timeout: {
      type: Number,
      default: 300
    }
  },
  ready() {
    if (this.search && this.multiple) {
      this.minWidth = '190px'
    }
    // 如果this.value不存在或正length不等于0
    if ((this.value === false ? false : !this.value) || this.value.length === 0) {
      if (this.valueSingle) {
        this.value = ''
      } else {
        this.value = []
      }
    } else {
      // 如果this.value不是数组
      if (this.value.constructor !== Array) {
        if (!this.valueSingle) {
          this.value = [this.value]
        }
      } else {
        // this.value不是数组并且不是多选
        if (!this.multiple && this.value.length > 1) {
          this.value = this.value.slice(0, 1)
        } else if (this.multiple && this.value.length > this.limit) {
          this.value = this.value.slice(0, this.limit)
        }
      }
    }
    let el = this.$els.dropdown
    let elbtn = this.$els.btn
    this._closeEvent = EventListener.listen(window, 'mouseup', (e) => {
      if (!el.contains(e.target) && this.show && !elbtn.contains(e.target)) {
        this.show = false
      }
    })
  },
  data() {
    return {
      left: '0',

      searchText: null,
      show: false,
      showNotify: false,
      paramsData: [],
      // isShowModify: false
      timer: null
    }
  },
  computed: {
    // 返回显示的选择内容
    selectedItems() {
      // 值为空，返回空串
      if (this.value === false ? false : !this.value) {
        return ''
      }
      if (this.value == null || this.value.length === 0) {
        return ''
      }
      // 把单选变成数组
      let value
      if (this.valueSingle) {
        value = [this.value]
      } else {
        value = this.value
      }

      // 根据value值，找到label
      let foundItems = []
      if (value === false ? true : value && value.length) {
        for (var item of value) {
          // 如果没有可选项，直接value内容
          // 改动 没有可选项 直接为空
          if (this.options.length === 0) {
            // foundItems = value;
            foundItems = [];
          }
          // 有可选项
          else {
            // 如果是对象，显示对象给定的列
            if (typeof item === "object") {
              for (let o of this.options) {
                // 选中对象鱼可选项value值相同，取选项的label
                if ((o.value === false ? true : o.value) && o.value[this.filerKey] === item[this.filerKey]) {
                  foundItems.push(o.label)
                  break
                }
              }
            } else {
              // 否则，显示值本身
              let option
              this.options.some(o => {
                if (o.value === item) {
                  option = o
                  return true
                }
              })
              option && foundItems.push(option.label)
            }
          }
        }
        if (foundItems.length === 0 || foundItems[0].constructor === Object) {
          return ''
        }
        //选中的
        let str = foundItems.join(', ')
        // if(str.length > 4)
        //   return str.substring(0,4)+'...'
        // else
        return str
      }
    },
    showPlaceholder() {
      if (this.value === false ? true : this.value) {
        return this.value.length === 0 || this.selectedItems === ''
      }
      return true
    }
  },
  watch: {
    value(val) {
      this.$emit('change', val)
      this.$emit('selected', this.selected)
      if (val && val.length > this.limit) {
        this.showNotify = true
        this.value.pop()
        setTimeout(() => this.showNotify = false, 1000)
      }
    },
    show() {
      this.judgBoundary();
    },
    searchText() {
      // 防抖
      if (this.timer) {
        clearTimeout(this.timer)
      }
      this.timer = setTimeout(() => {
        this.$emit('select-search', this.searchText)
      }, this.timeout)
    }
  },
  methods: {
    //全选
    selectAll(v) {
      this.isSelectAll = !this.isSelectAll
      if (this.searchText === null) {
        v.forEach((item) => {
          this.select(item.value, this.isSelectAll)
        })
      } else {
        let result = v.filter((item) => {
          return item.label.includes(this.searchText)
        }).forEach((item) => {
          this.select(item.value, this.isSelectAll)
        })
      }
    },
    select(v, flag) {
      if (flag == true) {
        if (this.multiple) {
          this.value.$remove(v)
          this.value.push(v)
        }
        if (this.closeOnSelect) {
          this.toggleDropdown()
        }
      } else if (flag == false) {
        if (this.multiple) {
          this.value.$remove(v)
        }
        if (this.closeOnSelect) {
          this.toggleDropdown()
        }
      } else if (flag == null) {
        if (this.valueSingle || !this.value || this.value.indexOf(v) === -1) {
          if (this.multiple) {
            this.value.push(v)
          } else {
            if (this.valueSingle) {
              this.value = v
            } else {
              this.value = [v]
            }
          }
        } else {
          if (this.multiple || this.value) {
            this.value.$remove(v)
          }
        }
        if (this.closeOnSelect) {
          this.toggleDropdown()
        }
      }
      this.judgBoundary();
    },
    isSelected(v) {
      if (this.value === false ? false : !this.value) {
        return false
      }
      if (this.value.constructor !== Array) {
        return this.value == v
      } else {
        return this.value.indexOf(v) !== -1
      }

    },
    toggleDropdown() {
      this.width = this.$els.group.clientWidth * this.width + 'px'
      this.show = !this.show
    },
    putOptions(val) {
      if (this.enterPush) {
        let sign = false
        this.options.forEach((item) => {
          if (val === item.label) {
            sign = true
          }
        })
        if (!sign) {
          let tmp = {label: val, value: val}
          this.options.push(tmp)
        }
        this.select(val, null)
      }
      this.judgBoundary();
    },
    judgBoundary() {
      //判断是否超出边界，超出移动
      if (document.documentElement.offsetWidth < this.$els.dropdown.getBoundingClientRect().right) {
        this.left = document.documentElement.offsetWidth - this.$els.dropdown.getBoundingClientRect().right - 25
      }
    }
  },
  beforeDestroy() {
    if (this._closeEvent) this._closeEvent.remove()
  }
}
</script>

<style scoped>
.bs-searchbox {
  padding: 4px 8px;
}

.menu-align-right {
  left: unset;
  right: 0;
}

.btn-group .dropdown-menu .notify {
  position: absolute;
  bottom: 5px;
  width: 96%;
  margin: 0 2%;
  min-height: 26px;
  padding: 3px 5px;
  background: #f5f5f5;
  /*border: 1px solid #e3e3e3;*/
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
  pointer-events: none;
  opacity: .9;
  overflow: hidden;
  text-overflow: ellipsis;
}

.select-style {
  border: 0px;
  /*border-bottom: 2px solid #C9CCCF;*/
  border: 1px solid #93B2D3;
  border-radius: 0px;
  color: #555;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 为新产品增加修改菜单选项 */
.vselect-self-style {
  text-align: center;
  border: 2px dashed #ccc;
  margin: 5px 10px;
  border-radius: 5px;
}

/* 当内容超过最大时，显示省略，长度不能超过最大值 */
.btn-group > button {
  max-width: 100%;
}

.btn-group > button .btn-content {
  max-width: 100%;
}
</style>
