<template>
  <transition :name="transitionName">
    <div
      v-show="visible && contentRelief"
      ref="tooltip"
      :class="[wrapperClass, theme, {large}]"
    >
      <div class="tooltip-content" :style="contentStyles" v-html="content"></div>
      <div ref="arrow" :class="[arrowClass, {large}]" x-arrow></div>
    </div>
  </transition>
</template>

<script>
import { LIB_NAME, ANIMATION_PREFIX, Popper, on, off } from '../../../../src/util'

export default {
  name: 'xTooltip',
  mixins: [Popper],
  props: {
    // 触发事件
    triggerEvent: {
      type: String,
      validator(v) {
        return ['click', 'mouseenter', 'manual'].includes(v)
      },
      default: 'mouseenter'
    },
    // 提示文本
    content: String, // eslint-disable-line
    // 主题
    theme: String, // eslint-disable-line
    // 提示框最大宽度
    maxWidth: String, // eslint-disable-line
    // 是否启用大号 Tooltip
    large: Boolean,
    // 当 triggerEvent 为 `manual` 的时候，控制 tooltip 是否显示
    reveal: Boolean,
    // 当 triggerEvent 为 `mouseenter`的时候，鼠标移到tip上时tip是否继续显示
    stay: Boolean
  },
  data() {
    return {
      wrapperClass: `${LIB_NAME}-tooltip`,
      arrowClass: `${LIB_NAME}-popper-arrow`,
      transitionName: `${ANIMATION_PREFIX}fade`,

      // content Substitute
      contentRelief: ''
    }
  },
  computed: {
    contentStyles() {
      return {
        maxWidth: this.maxWidth
      }
    },
    isHover() {
      return this.triggerEvent === 'mouseenter'
    }
  },
  mounted() {
    this.timer = null
    this.contentRelief = this.content
    this.registerEvent()
    if (this.triggerEvent === 'manual' && this.reveal) {
      this.show()
    }
  },
  destroyed() {
    this.timer && clearTimeout(this.timer)
    this.unRegisterEvent()
  },
  methods: {
    show() {
      this.visible = true
    },
    hide() {
      this.visible = false
    },
    handleMouseEnter() {
      this.timer && clearTimeout(this.timer)
      this.show()
    },
    handleMouseLeave() {
      this.timer && clearTimeout(this.timer)
      this.timer = setTimeout(() => {
        this.hide()
      }, 100)
    },
    update(options) {
      if (options.triggerEvent === 'manual') {
        if (options.reveal === false) {
          return this.hide()
        } else if (options.reveal === true) {
          this.show()
        }
      }
      this.contentRelief = options.text
      if (options.text) {
        this.content = options.text
      }
      this.theme = options.theme
      this.large = !!options.large
      this.maxWidth = options.maxWidth
      if (this.visible) {
        this.updateElementHandler()
      }
    },
    registerEvent() {
      const tooltip = this.$refs.tooltip
      if (!this.isHover || !this.stay || !tooltip) return

      on(tooltip, 'mouseenter', this.handleMouseEnter)
      on(tooltip, 'mouseleave', this.handleMouseLeave)
    },
    unRegisterEvent() {
      const tooltip = this.$refs.tooltip
      if (!tooltip) return

      off(tooltip, 'mouseenter', this.handleMouseEnter)
      off(tooltip, 'mouseleave', this.handleMouseLeave)
    }
  }
}
</script>
