<script>
import {prop, Timeout, Paster} from '@uif/next/lib/utils/tools'
import NPasterContent from './paster-content'

export default {
  name: 'n-paster',
  props: {
    // 贴片名：如果有wrap，则将有div包裹，如果没有，则由外部控制
    wrap: prop.string(),
    // 显示状态
    value: prop.boolean(),
    // 禁用
    disabled: prop.boolean(),
    // 触发方式，可选值为click, hover
    trigger: prop.inArray(['click', 'hover'], 'click'),
    /**
     * content
     * **/
    // 贴片子组件
    contentComponent: prop.object(null),
    // 贴片子组件 props
    contentProps: prop.object(),
    /**
     * 触发器
     * **/
    // 触发位置
    placement: prop.placement('bottom-start'),
    // 文本对齐
    offset: prop.array(() => [0, 8]),
    // 提示框宽度
    width: prop.stringNumber(),
    // 文本对齐
    align: prop.inArray(['left', 'center', 'right'], null, true),
    // 其他参数
    options: prop.object(),
    // 延迟2分钟自动销毁
    autoDestroy: prop.boolean(true)
  },
  data () {
    return {
      nValue: false
    }
  },
  watch: {
    value (value) {
      this.setNValue(value)
    },
    nValue (nValue) {
      if (this.value !== nValue) {
        this.$emit('input', nValue)
        this.$emit('update:value', nValue)
      }
    }
  },
  render (h) {
    const {wrap, onClick, onMouseenter, onMouseleave, $scopedSlots} = this
    if (!wrap) {
      return $scopedSlots.default?.({onClick, onMouseenter, onMouseleave})
    }
    return h('div', {staticClass: wrap, on: {click: onClick, mouseenter: onMouseenter, mouseleave: onMouseleave}}, $scopedSlots.default?.())
  },
  mounted () {
    this.time = new Timeout()
    if (this.value) {
      this.setNValue(true)
    }
  },
  methods: {
    setNValue (value) {
      if (this.nValue !== value) {
        this.nValue = value
        this.updatePaster()
      }
    },
    // 点击事件
    onClick () {
      if (this.trigger !== 'hover' && !this.disabled) {
        this.setNValue(true)
      }
    },
    // 鼠标 enter
    onMouseenter () {
      if (!this.disabled && this.trigger === 'hover') {
        this.time.out(() => this.setNValue(true), 100)
      }
    },
    // 鼠标 leave
    onMouseleave () {
      if (!this.disabled && this.trigger === 'hover') {
        this.time.out(() => this.setNValue(false), 200)
      }
    },
    // 更新 paster
    updatePaster () {
      this.paster = this.paster || new Paster({
        reference: this.$el,
        ctor: {
          creator: this,
          component: this.contentComponent || NPasterContent,
          props: this.contentProps,
          scopedSlots: this.$scopedSlots,
          nativeOn: {
            mouseenter: () => this.onMouseenter(),
            mouseleave: () => this.onMouseleave()
          }
        },
        options: {
          placement: this.placement,
          offset: this.offset,
          styles: {
            width: this.width + 'px',
            textAlign: this.align
          },
          ...this.options
        },
        autoDestroy: this.autoDestroy,
        handleClickOutside: this.trigger === 'click',
        onStateChange: (value) => this.setNValue(value)
      })
      return this.nValue ? this.paster.show() : this.paster.hidden()
    },
    // 更新
    update () {
      return this.paster?.popperEngine?.update()
    }
  }
}
</script>
