/**
 * 选择框
 * @author niewei
 */
import ProLayoutFormitem from 'mars-pro/packages/pro-layout-formitem';
import ProSelectCascader from 'mars-pro/packages/pro-select-cascader';
import ProSelectGrouplist from 'mars-pro/packages/pro-select-grouplist';
import ProSelectChecks from 'mars-pro/packages/pro-select-checks';
import ProSelectList from 'mars-pro/packages/pro-select-list';
import ProSelectRadios from 'mars-pro/packages/pro-select-radios';
import ProSelectTable from 'mars-pro/packages/pro-select-table';
import ProSelectTree from 'mars-pro/packages/pro-select-tree';
import ProSelectTags from 'mars-pro/packages/pro-select-tags';
import omit from 'mars-pro/src/pro/omit';
import ProDetail from 'mars-pro/packages/pro-detail'

import { PRO_CONFIG_PROVIDE_CONTEXT } from 'mars-pro/packages/pro-config-provide';
import debounce from 'throttle-debounce/debounce';
import { getElementWidth, getSingleTextWidth,stopAndPreventDomEvent } from 'mars-pro/src/pro/util';

export default {
  name: 'ProSelect',

  componentName: 'ProSelect',

  components: {
    ProSelectCascader,
    ProSelectGrouplist,
    ProSelectChecks,
    ProSelectList,
    ProSelectRadios,
    ProSelectTable,
    ProSelectTree,
    ProLayoutFormitem,
    ProSelectTags,
    ProDetail
  },
  inject: {
    elForm: {
      default: "",
    },
    elFormItem: {
      default: "",
    },
    proDetail: {
      default: ''
    },
    [PRO_CONFIG_PROVIDE_CONTEXT]: {
        default: null
    }
  },
  props: {
    uiType: {
      type: String,
      default: 'list'
    },
    layout: {
      type: Boolean,
      default: true
    },
    value: [String, Object, Array, Number],
    showOverTooltip:{
      type: Boolean,
      default: true
    }
  },
  computed: {
    enableDetail() {
      const thisEnableDetail = this.$attrs.enableDetail
      if(typeof thisEnableDetail === 'boolean'){
        return thisEnableDetail
      }
      return (this.elForm && this.elForm.enableDetail === true ) || !!this.proDetail
    },
    _elFormItemSize() {
      return (this.elFormItem || {}).elFormItemSize;
    },
    inputSize() {
      return this.$attrs.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
    }
  },
  created() {
    // global tooltip
    this.activateGlobalTooltip = debounce(500, tooltip => tooltip.handleShowPopper());
  },
  methods: {
    getConfigProvide() {
      return this[PRO_CONFIG_PROVIDE_CONTEXT]
    },
    handleMouseenters(e){
      stopAndPreventDomEvent(e)
        if (this.hasTooltipWappers() === true) {
            return;
        }
        const configProvide = this.getConfigProvide()
        const globalTooltipScope = configProvide.proGlobalTooltip
        const tooltip = globalTooltipScope.$refs.proGlobalTooltip;
        const refEl = this.$el
        const elInput = refEl.getElementsByTagName('span')[0] || refEl
        // 计算是否需要显示
        const textWidth = getSingleTextWidth(refEl.innerText, window.getComputedStyle(elInput).fontSize)
        const inputWidth = getElementWidth(refEl)
        if (textWidth < inputWidth) {
            return
        }
        globalTooltipScope.tooltipContent = elInput.innerText
        tooltip.referenceElm = refEl;
        tooltip.$refs.popper && (tooltip.$refs.popper.style.display = 'none');
        tooltip.doDestroy();
        tooltip.setExpectedState(true);
        this.activateGlobalTooltip(tooltip)
    },
    handleMouseleaves(e){
      stopAndPreventDomEvent(e)
      if (this.hasTooltipWappers() === true) {
          return
      }
      const configProvide = this.getConfigProvide()
      if (configProvide && configProvide.proGlobalTooltip) {
          const globalTooltipScope = configProvide.proGlobalTooltip
          const tooltip = globalTooltipScope.$refs.proGlobalTooltip;
          tooltip.setExpectedState(false);
          tooltip.handleClosePopper();
      }
    },
    //判断是否被tooltip包裹
    hasTooltipWappers() {
        var parent = this.$parent || this.$root;
        var name = parent.$options.name;
        while (parent) {
            if ('ElTooltip' === name || 'ElTableRow' === name) {
                return true
            }
            parent = parent.$parent;
        }
        return false
    },
    renderSlots() {
      const slots = omit(this.$slots || {}, ['default'])
      return Object.keys(slots).map(item => (
        <template slot={item}>{slots[item]}</template>
      ))
    },
    renderSelect(type) {
      const _proselect = {
        props: {
          ...this.$attrs,
          value: this.value
        },
        attrs: this.$attrs,
        on: this.$listeners,
        'class': {
          'pro-select': true
        },
        ref: 'proselect',
        scopedSlots: this.$scopedSlots,
      }
      if (type === 'cascader') {
        return <ProSelectCascader {..._proselect}>{this.renderSlots()}</ProSelectCascader>
      } else if (type === 'tree') {
        return <ProSelectTree {..._proselect}>{this.renderSlots()}</ProSelectTree>
      } else if (type === 'table') {
        return <ProSelectTable {..._proselect}>{this.renderSlots()}</ProSelectTable>
      } else if (type === 'radios') {
        return <ProSelectRadios {..._proselect}>{this.renderSlots()}</ProSelectRadios>
      } else if (type === 'checks') {
        return <ProSelectChecks {..._proselect}>{this.renderSlots()}</ProSelectChecks>
      } else if (type === 'group' || type === 'grouplist') {
        return <ProSelectGrouplist {..._proselect}>{this.renderSlots()}</ProSelectGrouplist>
      } else if (type === 'tags') {
        return <ProSelectTags {..._proselect}>{this.renderSlots()}</ProSelectTags>
      } else {
        return <ProSelectList {..._proselect} />
      }
    }
  },
  render() {
    const _formItemDatas = {
      props: {
        ...this.$attrs,
      },
      attrs: {
        ...this.$attrs,
      },
      on: this.$listeners,
      'class': {
        'detail': this.enableDetail
      }
    }

    //详情模式
    const _detailDatas = {
      props: {
        value: this.value,
        dataSource: this.dataSource,
        detailType: 'select',
        ...this.$attrs
      },
      attrs: {
        ...this.$attrs
      },
      scopedSlots: this.$scopedSlots,
      'class': {
        [`el-input--${this.inputSize}`]: true
      },
      nativeOn: {
        ...(this.showOverTooltip ? {
          mouseenter: this.handleMouseenters,
          mouseleave: this.handleMouseleaves,
          click: this.handleMouseleaves
        } : {})
      }
    }
    const detailVnode = (
      <div class="detail-wapper">
        <pro-detail {..._detailDatas}>
          {this.$slots.default}
          {this.renderSlots()}
        </pro-detail>
      </div>
    )
    return (
      this.layout
        ? <ProLayoutFormitem {..._formItemDatas}>
          {this.enableDetail !== true ? this.renderSelect(this.uiType) : detailVnode}
          {this.renderSlots()}
        </ProLayoutFormitem>
        : this.renderSelect(this.uiType)
    )
  }
}

