<template>
  <div class="uif-popper" v-clickoutside.capture="onClickOutside">
    <div ref="reference" class="uif-popper-reference" :class="referenceClass" @click="handleVisible"><slot name="reference"></slot></div>
    <transition :name="transition" @before-enter="update()" @after-leave="destroy()">
      <div ref="popper" class="uif-popper-popper" :class="popperClass" :style="styles" v-show="value"><slot name="popper"></slot></div>
    </transition>
  </div>
</template>

<script>
import {clickoutside} from '@uif/core/lib/utils/next'
import {transferIncrease} from '@uif/core/lib/utils/transfer'
import {insertAfter} from '@uif/core/lib/utils/dom'
import popper from '@uif/core/lib/utils/popper'
import {px} from '@uif/core/lib/utils/assist'

export default {
  name: 'u-popper',
  mixins: [popper],
  directives: {
    clickoutside
  },
  props: {
    referenceClass: {
      default: ''
    },
    popperClass: {
      default: ''
    },
    value: {
      type: Boolean,
      default: false
    },
    disabled: {
      type: Boolean,
      default: false
    },
    transfer: {
      type: Boolean,
      default: false
    },
    transition: {
      type: String,
      default: ''
    },
    width: {
      type: [String, Number],
      default: ''
    },
    minWidth: {
      type: [String, Number],
      default: ''
    }
  },
  data () {
    return {
      tIndex: transferIncrease()
    }
  },
  computed: {
    styles () {
      const style = {}
      if (this.width) style.width = px(this.width)
      if (this.minWidth) style.minWidth = px(this.minWidth)
      if (this.transfer) style['z-index'] = 1060 + this.tIndex
      return style
    }
  },
  watch: {
  },
  mounted () {
  },
  beforeDestroy () {
    this.destroy()
  },
  methods: {
    handleVisible () {
      if (this.disabled) return false
      this.setValue(!this.value)
    },
    // 外部点击事件处理
    onClickOutside (event) {
      if (this.value) {
        if (this.transfer) {
          const popper = this.getPopper()
          if (popper === event.target || popper.contains(event.target)) {
            return false
          }
        }
        this.setValue(false)
      }
    },
    setValue (value) {
      if (this.value !== value) {
        this.$emit('input', value)
      }
    },
    getRefReference () {
      return this.$refs.reference
    },
    getPopper () {
      return this.$refs.popper
    },
    update () {
      if (this.transfer) {
        this.transferEl()
      }
      this.updatePopper()
      this.tIndex = transferIncrease()
    },
    destroy () {
      if (this.transfer) {
        this.resetEl()
      }
      this.destroyPopper()
    },
    // 将节点挂载到body上
    transferEl () {
      const popper = this.getPopper()
      if (popper && popper.parentNode !== document.body) {
        document.body.appendChild(popper)
      }
    },
    // 将节点放回原位置
    resetEl () {
      const reference = this.getRefReference()
      const popper = this.getPopper()
      if (reference && popper && popper.parentNode === document.body) {
        insertAfter(popper, reference)
      }
    }
  }
}
</script>
