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

export default {
  name: 'n-options',
  props: {
    // 贴片名：如果有wrap，则将有div包裹，如果没有，则由外部控制
    wrap: prop.string(),
    // 是否可见
    value: prop.boolean(),
    // 禁用
    disabled: prop.boolean(),
    // 是否多选
    multiple: prop.boolean(),
    /**
     * paster
     * **/
    // 触发方式，可选值为click, hover
    trigger: prop.inArray(['click', 'hover'], 'click'),
    // 提示框宽度
    width: prop.stringNumber(),
    // 自定义选项
    pasterOptions: prop.object(),
    /**
     * options
     * **/
    // SearchState
    state: prop.object(),
    // 开启虚拟滚动
    virtual: prop.boolean(),
    // 选项
    options: prop.array(),
    // 最大高度
    maxHeight: prop.number(270),
    // 自定义渲染
    builders: prop.object(() => ({
      header: null,
      option: null,
      footer: null,
      empty: null
    })),
    // 延迟2分钟自动销毁
    autoDestroy: prop.boolean(),
    // 点击自动关闭 ADD
    autoClose: prop.boolean(true),
    // 处理点击外部 click：默认关闭
    handleClickOutside: {
      type: [Function, Boolean],
      default: true
    }
  },
  data () {
    return {
      pasterCtorComponent: NOptionsPaster,
      nValue: false,
      time: new Timeout()
    }
  },
  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?.())
  },
  watch: {
    value (value) {
      this.setNValue(value)
    },
    nValue (nValue) {
      if (this.value !== nValue) {
        this.$emit('input', nValue)
        this.$emit('update:value', nValue)
      }
    },
    // options 变更，更新 props
    options (value) {
      return this.paster?.popperComponent?.setProps('options', value)
    }
  },
  methods: {
    // 点击
    onOptionClick (option) {
      this.$emit('click', option)
      this.$emit('u-change', option)
      this.autoClose && this.setNValue(false)
    },
    /**
     * paster
     * **/
    // 设置状态
    setNValue (value) {
      if (this.nValue !== value) {
        this.nValue = value
        this.updatePaster()
      }
    },
    // 点击
    onClick () {
      if (!this.disabled && this.trigger === 'click') {
        this.setNValue(true)
      }
    },
    // 鼠标移入
    onMouseenter () {
      if (!this.disabled && this.trigger === 'hover') {
        this.time.out(() => this.setNValue(true), 100)
      }
    },
    // 鼠标移出
    onMouseleave () {
      if (!this.disabled && this.trigger === 'hover') {
        this.time.out(() => this.setNValue(false), 200)
      }
    },
    // 展开选项
    updatePaster () {
      this.paster = this.paster || new Paster({
        reference: this.$el,
        ctor: {
          creator: this,
          component: this.pasterCtorComponent,
          props: {
            virtual: this.virtual,
            builders: this.builders,
            maxHeight: this.maxHeight,
            multiple: this.multiple,
            state: this.state,
            options: this.options,
            index: 1
          },
          scopedSlots: this.$scopedSlots,
          nativeOn: {
            mouseenter: this.onMouseenter,
            mouseleave: this.onMouseleave
          },
          on: {
            'option-click': this.onOptionClick,
            'select-all': (options, value) => this.$emit('select-all', options, value),
            'on-confirm': () => this.$emit('on-confirm')
          }
        },
        options: {
          placement: 'bottom-start',
          offset: [0, 4],
          styles: {
            width: this.width + 'px'
          },
          ...this.pasterOptions
        },
        autoDestroy: this.autoDestroy,
        onStateChange: (value) => this.setNValue(value),
        handleClickOutside: this.handleClickOutside
      })
      this.nValue ? this.paster.show() : this.paster.hidden()
    }
  }
}
</script>
