<template>
  <div :class="classes" :style="selectStyles" v-docClick="close" v-winScroll="handleScroll">
    <div :class="selectClass" @click="toggleDrop" ref="rel">
       <y-tag v-if="selectedTag.length"
          v-for="(item, index) in selectedTag"
          :key="index"
          type="info"
          :label="item.name"
          :id="item.id"
          :index="index" @close="tagDel">
       </y-tag>
      <input type="text" class="k-select-label" placeholder="请选择"
      v-if="!selectedTag.length"
      v-model="label"
      :readonly="!filterable||disabled"
      :disabled="disabled"
      @keyup="handleKeyup"
      ref="input" />
      <span class="k-select-arrow"></span>
    </div>
    <transition name="dropdown">
      <div class="k-select-dropdown" ref="dom" v-if="!wordselector" v-show="visible" :style="dropdownStyles" v-transferDom :data-transfer="transfer">
        <ul>
          <slot></slot>
          <li class="k-select-item k-select-item-nodata" v-if="children.length==0|| queryCount==0">{{nodata}}</li>
        </ul>
      </div>
      <div class="k-select-dropdown k-select-word-dropdown" ref="wordselect" v-else v-show="visible" :style="dropdownStyles" v-transferDom>
         <wordpane @toSelector="getWordVal" :selectedTag="selectedTag"></wordpane>
      </div>
    </transition>
  </div>
</template>
<script>
import emitter from "yt-ui/src/mixins/emitter";
import transferDom from "yt-ui/src/directives/transferDom";
import winScroll from "yt-ui/src/directives/winScroll";
import docClick from "yt-ui/src/directives/docClick";
import ytag from "./tag.vue";
import wordpane from "./wordpane.vue";
// import transferDom from "yt-ui/src/packages/transferDom";
export default {
  name: "YSelect",
  directives: { docClick, transferDom, winScroll },
  mixins: [emitter],
  props: {
    remoteMethod: {type: Function},
    filterable: Boolean,
    transfer: { type: Boolean, default: true },
    width: { type: [Number, String], default: 0 },
    value: { type: [String, Number], default: "" },
    clearable: { type: Boolean, default: false },
    disabled: { type: Boolean, default: false },
    wordselector: { type: Boolean, default: false }, // 标签选择器带字母搜索下拉
    nodata: {type: String, default: '暂无数据'}
    // remoteData: {type: Array, default: function () {
        // return []}} // 标签选择器的数据
  },
  watch: {
    value(v,v2) {
      this.updateSelect(v);
    },
    visible(val) {
      if (this.filterable) {
        console.log(this.queryCount, 'queryCount')
        if (!val) {
          this.$nextTick(() => {
            this.children.forEach(x => (x.visible = true));
          });
          this.$refs.input.blur();
          this.label = (this.selectItem && this.trim(this.selectItem.label)) || "";
        }
      }
      this.$emit('open-change', val);
    }
  },
  data() {
    return {
      visible: false,
      dropdownWith: 0,
      left: 0,
      fadeInBottom: false,
      top: 0,
      label: "",
      children: [],
      queryCount: 0,
      selectItem: null,
      selectedTag: []
    };
  },
  created() {
    this.$on("select-change", this.change);
    this.$on("select-add", this.add);
    this.$on("select-remove", this.remove);
  },
  mounted() {
    let value = this.value;
    if (!value && value !== 0) {
      this.label = "";
      this.selectItem = null;
    }
  },
  computed: {
    classes() {
      return [
        "k-select",
        {
          ["k-select-disabled"]: this.disabled,
          ["k-select-open"]: this.visible
        }
      ];
    },
    selectClass() {
      return [
        "k-select-selection",
        {
          ["k-select-isclearable"]: this.clearable && this.label
        }
      ];
    },
    selectStyles() {
      return this.width > 0 ? { width: `${this.width}px` } : {};
    },
    dropdownStyles() {
      let style = {};
      let top = this.top
      if (!this.wordselector) {
        style.width = `${this.dropdownWith}px`;
      } else {
        top = top + 29
      }
      console.log(top, 'top3')
      style.left = `${this.left}px`;
      style.top = `${top}px`;
      if (this.fadeInBottom) {
        style["transform-origin"] = "center bottom";
      }
      return style;
    }
  },
  updated() {
    this.handleScroll();
  },
  methods: {
    remove(obj) {
      this.children.splice(this.children.indexOf(obj), 1);
    },
    add(child) {
      this.queryCount++;
      child.index = this.children.length;
      let value = this.value;
      child.selected = child.value == value && (this.notNull(value));
      if (child.selected) {
        this.label = child.label === undefined ? child.$el.innerText : child.label
        this.selectItem = { label: this.label, value: child.value }
      }
      this.children.push(child);
    },
    handleKeyup(e) {
      if (!this.filterable) return
      // 内容清空
      if (!this.label && this.label !== 0) {
        this.selectItem = {}
        this.children.forEach(child => {
           child.selected = false
        })
      }
      // 远程搜索
      if (typeof this.remoteMethod === 'function') {
        this.remoteMethod(e.target.value)
      }
      // 调用option的query
      this.children.forEach(x => x.query(e.target.value))
      this.queryCount = this.children.filter(x => x.visible).length
      this.handleScroll()
    },
    close() {
      this.visible = false;
    },
    updateSelect(value) {
      let isNotValue = this.notNull(value);
      this.children.forEach(child => {
        child.selected = isNotValue && value == child.value

        if (child.selected) this.label = child.label === undefined ? child.$el.innerText : child.label
      });
      if (this.isNull(value)) this.label = ''
    },
    toggleDrop() {
      if (this.disabled) {
        return false;
      }
      this.dropdownWith = this.$refs.rel.offsetWidth;
      this.visible = !this.visible;

      this.handleScroll();
    },
    handleScroll() {
      this.$nextTick(() => this.setPosition());
    },
    setPosition() {
      let m = 0;
      let rel = this.$refs.rel;
      let dom = this.$refs.dom;
      if (!dom) return;
      this.dropdownWith = rel.offsetWidth;
      let relPos = this.getElementPos(rel);
      let clientH = window.innerHeight;
      let clientW = window.innerWidth;
      // console.log(relPos)
      let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
      let scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;

      let domH = dom.offsetHeight;
      let relH = rel.offsetHeight;
      if (this.transfer) this.left = relPos.left + scrollLeft;
      //new
      if (clientH - relPos.top - relH - m < domH) {
        //空出来的高度不足以放下dom
        this.fadeInBottom = true;
        this.top = this.transfer
          ? relPos.top - m - domH + scrollTop
          : -(domH + m);
      } else {
        this.fadeInBottom = false;
        this.top = this.transfer ? relPos.top + relH + m + scrollTop : relH + m;
      }
      // console.log(this.top)
      //console.log(this.fadeInBottom, clientH, relPos.y, relH, m, domH)
      //old
      // if (h - (pos.y - s) - rh < dh) {
      //   this.fadeInBottom = true;
      //   this.top = !this.transfer ? -dh - m : pos.y - dh - m;
      // } else {
      //   this.fadeInBottom = false;
      //   this.top = !this.transfer ? rh + m : pos.y + rh + m;
      // }
    },
    change(item) {
      this.selectItem = item;
      this.label = item.label;
      //针对value没有定义的情况
      this.$emit("input", item.value);
      if (this.value === '') {
        this.children.forEach(child => {
          child.selected = item.value == child.value
        });
      }
      this.children.forEach(child => {
        child.resetHight()
      });
      this.$emit("change", item);

      this.dispatch("FormItem", "form-item-change", item.value);
      this.$nextTick(() => (this.visible = false));
    },
    getWordVal (name, id) {
      this.selectedTag.push({name, id})
      // this.setPosition()
      // if (this.top > 61) {
      this.$nextTick(() => {
        this.top = Number(this.$refs.rel.offsetHeight || this.$refs.rel.clientHeight) - 30
      })
      // }
      // console.log(this.top, 'top')
    },
    // 删除标签
    tagDel (index, id) {
      this.selectedTag.splice(index, 1)
      this.$nextTick(() => {
        this.top = Number(this.$refs.rel.offsetHeight || this.$refs.rel.clientHeight) - 30
      })
      // this.setPosition()
      // console.log(this.top, 'top2')
    },
    trim (str) {
      if (!str) return str
      return str.replace(/\s/g, '')
    },
    isNull (value) {
      return value === "" || value === undefined || value === null
    },
    notNull (value) {
      return value !== "" && value != undefined && value !== null
    }
  },
  components: {ytag, wordpane}
};
</script>

