<script>
import { mapState } from 'vuex'
const globalIndex = Math.random()

function getKey() {
  return Math.random()
    .toString()
    .substr(3, 10)
}
export default {
  name: 'my-table',
  components: {},
  props: {
    rowKey: {
      type: String,
      default: '_id',
    },
    tableColumns: {
      type: Array,
      default: () => [],
    },
    sourceData: {
      type: Array,
      default: () => [],
    },
    selectMore: {
      type: Boolean,
      default: false,
    },
    // 排序
    serverSort: {
      type: Boolean,
      default: false,
    },
    treeConfig: {
      type: Object,
      default: () => { },
    },
    expandConfig: {
      type: Object,
      default: () => { },
    },
    stripe: {
      type: Boolean,
      default: false,
    },
    showHeader: {
      type: Boolean,
      default: true,
    },
    isFooter: {
      type: Boolean,
      default: false,
    },
    more: {
      type: Boolean,
      default: false,
    },
    pageSize: {
      type: Number,
      default: 100,
    },
    serialNumber: {
      type: Boolean,
      default: true,
    },
    selection: {
      type: Boolean,
      default: false,
    },
    radio: {
      type: Boolean,
      default: false,
    },
    footerMethod: {
      type: Function,
      default: () => { },
    },
    cellClick: {
      type: Function,
      default: () => { },
    },
    footerSpanMethod: {
      type: Function,
      default: () => { },
    },
    rowClassName: {
      type: Function,
      default: () => { },
    },
    cellStyle: {
      type: Function,
      default: () => { },
    },
    highIds: {
      // 高亮显示行
      type: Array,
      default: () => [],
    },
    highFirst: {
      type: Boolean,
      default: false,
    },
    spanMethod: {
      type: Function,
      default: () => { },
    },
    checkboxConfig: {
      type: Object,
      default: () => { },
    },
    customRightMenu: {
      type: Object,
      default: () => ({
        code: '',
        name: '',
        prefixIcon: '',
        disabled: false,
      }),
    },
    virtualScroll: {
      type: Boolean,
      default: true,
    },
    cellClassName: {
      type: Function,
    },
  },
  computed: {
    ...mapState({
      keyCode: 'keyCode',
      // oldSelection: (state) => state.Order.oldSelection,
    }),
    tableMenu() {
      const obj = {
        header: {
          options: [
            [
              {
                code: 'hideColumn',
                name: '隐藏列',
                disabled: false,
              },
              {
                code: 'showAllColumn',
                name: '取消所有隐藏列',
                disabled: false,
              },
            ],
          ],
        },
        body: {
          options: [
            [
              {
                code: 'checkAll',
                name: '全部选择',
                disabled: false,
              },
              {
                code: 'cancelSelection',
                name: '取消选择',
                disabled: true,
              },
              {
                code: 'copy',
                name: '复制',
                prefixIcon: 'fa fa-copy',
                disabled: false,
              },
            ],
          ],
        },
        // visibleMethod: this.visibleMethod
      }
      if (this.$props.customRightMenu?.name) {
        const {
          code,
          name,
          prefixIcon,
          disabled,
        } = this.$props.customRightMenu
        obj.body.options[0].push({
          code,
          name,
          prefixIcon,
          disabled,
        })
      }
      return obj
    },
  },
  watch: {
    sourceData(data) {
      this.$refs.vxetable.clearCheckboxRow()
      setTimeout(() => {
        if (data.length > 0 && this.highFirst) {
          if (this.selection) {
            this.$refs.vxetable.setCheckboxRow(
              [data[0]],
              true,
            )
          } else if (this.radio) {
            this.$refs.vxetable.setRadioRow(
              this.sourceData[0],
            )
            this.$refs.vxetable.setCurrentRow(data[0])
          } else {
            this.$refs.vxetable.setCurrentRow(data[0])
          }
          this.$emit('selectionChange', [data[0]])
          this.$emit('currentChange', { row: data[0] })
        } else {
          this.$emit('selectionChange', [])
          this.$emit('currentChange', { row: null })
        }
      }, 100)
    },
    tableColumns(newdata, olddata) {
      console.log('tableColumns')
      if (
        newdata &&
        olddata &&
        olddata.length > 0 &&
        newdata !== olddata
      ) {
        this.tableKey = getKey()
        setTimeout(() => {
          if (
            this.sourceData.length > 0 &&
            this.highFirst
          ) {
            if (this.selection) {
              this.$refs.vxetable.setCheckboxRow(
                [this.sourceData[0]],
                true,
              )
            } else if (this.radio) {
              this.$refs.vxetable.setRadioRow(
                this.sourceData[0],
              )
              this.$refs.vxetable.setCurrentRow(
                this.sourceData[0],
              )
            } else {
              this.$refs.vxetable.setCurrentRow(
                this.sourceData[0],
              )
            }
            this.$emit('selectionChange', [
              this.sourceData[0],
            ])
            // this.$emit('currentChange', { row: this.sourceData[0] })
          }
        }, 200)
      }
    },
    // oldSelection(list) {
    //   setTimeout(() => {
    //     this.$refs.vxetable.clearCheckboxRow()
    //     this.$refs.vxetable.setCheckboxRow(list, true)
    //     this.$emit('selectionChange', list)
    //     this.$emit('currentChange', { row: null })
    //   }, 200)
    // },
    selection() {
      this.tableKey = getKey()
    },
  },
  data() {
    return {
      loading: false,
      notSelected: false,
      tableData: [],
      selections: [],
      startIndex: null,
      tableKey: getKey(),
    }
  },
  methods: {
    reloadData() {
      this.$refs.vxetable.reloadData(this.sourceData)
    },
    clearSelectionBox() {
      this.$refs.vxetable.clearCheckboxRow()//  清空表格左侧的选择框数据
    },
    toggleRowExpand(obj) {
      this.$emit('toggleRowExpand', obj)
    },
    syncResize() {
      if (this.selectMore && this.notSelected) {
        return '1'
      } else {
        return '2'
      }
    },
    setCheckboxRow(rows, checked) {
      this.$nextTick(() => {
        this.$refs.vxetable.clearCheckboxRow()
        this.$refs.vxetable.setCheckboxRow(rows, checked)
        this.$emit('selectionChange', rows)
      })
    },
    // 行点击
    currentChange(options) {
      const { row, $rowIndex } = options
      if (this.keyCode) {
        if (this.keyCode === 'Shift') {
          this.$refs.vxetable.clearCheckboxRow()
          let m, l
          if ($rowIndex > this.startIndex) {
            m = this.startIndex
            l = $rowIndex
          } else {
            m = $rowIndex
            l = this.startIndex
          }
          const arr = []
          for (let i = m; i <= l; i++) {
            arr.push(this.sourceData[i])
          }
          this.$refs.vxetable.setCheckboxRow(arr, true)
          this.$emit('selectionChange', arr)
        } else if (this.keyCode === 'Control') {
          this.$refs.vxetable.setCheckboxRow([row], true)
          const arr1 = this.$refs.vxetable.getCheckboxRecords()
          this.$emit('selectionChange', arr1)
        } else {
          this.startIndex = $rowIndex
          this.$emit('currentChange', options)
          try {
            if (this.selection) {
              this.$refs.vxetable.clearCheckboxRow()
              this.$refs.vxetable.setCheckboxRow(
                [row],
                true,
              )
              this.$emit('selectionChange', [options.row])
            }
            if (this.radio) {
              this.$refs.vxetable.clearRadioRow()
              this.$refs.vxetable.setRadioRow(row)
              this.$emit('selectionChange', [options.row])
            }
          } catch (error) {
            this.$alert(error, '错误提示')
          }
        }
      } else {
        this.startIndex = $rowIndex
        this.$emit('currentChange', options)
        try {
          if (this.selection) {
            this.$refs.vxetable.clearCheckboxRow()
            this.$refs.vxetable.setCheckboxRow([row], true)
            this.$emit('selectionChange', [options.row])
          }
          if (this.radio) {
            this.$refs.vxetable.clearRadioRow()
            this.$refs.vxetable.setRadioRow(row)
            this.$emit('selectionChange', [options.row])
          }
        } catch (error) {
          this.$alert(error, '错误提示')
        }
      }
    },
    // 单选
    radioChange(options) {
      this.$emit('currentChange', options)
      this.$emit('selectionChange', [options.row])
    },
    // 多选
    checkboxChange({ records }) {
      if (records > 0) {
        this.tableMenu.body.options[0][1].disabled = false
      } else {
        this.tableMenu.body.options[0][1].disabled = true
      }
      this.$emit('selectionChange', records)
    },
    // 全选
    checkboxAll({ records, checked }) {
      this.notSelected = checked
      if (records > 0) {
        this.tableMenu.body.options[0][1].disabled = false
      } else {
        this.tableMenu.body.options[0][1].disabled = true
      }
      if (checked) {
        this.$emit('selectAll', false)
      }
      this.$emit('selectionChange', records)
    },
    // 复制
    copyText(text) {
      const input = document.createElement('input')
      // input.style.display = 'none'
      document.body.appendChild(input)
      input.value = text
      input.select()
      if (document.execCommand('copy')) {
        document.execCommand('copy')
      }
      document.body.removeChild(input)
    },
    selectAll(e) {
      e && e.stopPropagation()
      this.$emit('selectAll', true)
    },
    // 右键菜单
    menuClick({ menu, row, column, $event }) {
      switch (menu.code) {
        case 'copy': // 复制
          if (row && column) {
            let text = $event.target.innerHTML
            if (/<.+?>/g.test(text)) {
              text = row[column.property]
            }
            if (!text) {
              text = 'null'
            }
            this.copyText(text)
          }
          break
        case 'checkAll': // 全选
          this.$refs.vxetable.setAllCheckboxRow(true)
          this.tableMenu.body.options[0][0].disabled = true
          this.tableMenu.body.options[0][1].disabled = false
          //  this.$set(this.tableMenu.body.options[0][0],'disabled',true)
          break
        case 'cancelSelection': // 取消全选
          this.$refs.vxetable.setAllCheckboxRow(false)
          this.tableMenu.body.options[0][0].disabled = false
          this.tableMenu.body.options[0][1].disabled = true
          //  this.$set(this.tableMenu.body.options[0][0],'disabled',true)
          break
        case 'hideColumn': // 隐藏列
          if (!column.property) {
            return this.$message.warning(
              '当前列不支持此操作',
            )
          }
          this.$emit('columnChange', {
            column: column.property,
            key: 'show',
            value: false,
          })
          //  this.$set(this.tableMenu.body.options[0][0],'disabled',true)
          break
        case 'showAllColumn': // 显示所有列
          this.$emit('columnChange', {
            column: 'all',
            key: 'show',
            value: true,
          })
          //  this.$set(this.tableMenu.body.options[0][0],'disabled',true)
          break
      }
      if (this.$props.customRightMenu?.func) {
        if (
          this.$props.customRightMenu.code === menu.code
        ) {
          this.$props.customRightMenu.func(
            row,
            column,
            $event,
          )
        }
      }
    },
    // 排序
    sortChange({ property, order }) {
      this.$emit('sortChange', { property, order })
    },
    // 手动设置排序
    setSort({ order, prop }) {
      this.$refs.vxetable.sort(prop, order)
    },

    showToggle() {
      this.loading = !this.loading
    },
    getIndex(index) {
      return globalIndex + index
    },
    // 列宽拖动
    resizableChange({ column }) {
      this.$emit('columnChange', {
        column: column.property,
        key: 'width',
        value: column.resizeWidth,
      })
    },
    renderColumn(item, index, classname) {
      const slots = {
        default: ({ row, $rowIndex }) => {
          if (item.type) return null
          if (item.render) {
            return item.render(row, item.key, $rowIndex)
          }
          return row[item.key]
        },
      }
      if (item.content) {
        slots.content = ({ row }) =>
          item.content ? item.content(row, item.key) : null
      }
      if (item.title) {
        slots.header = () =>
          item.title ? item.title(item.label) : item.label
      }
      return (
        <vxe-table-column
          type={item.type}
          title={item.label}
          field={item.key}
          tree-node={item.treeNode}
          fixed={item.fixed}
          header-class-name={classname}
          key={this.getIndex(index)}
          width={item.width}
          min-width={item.minWidth}
          header-align="center"
          sortable={item.sortable}
          align={item.align || 'center'}
          scopedSlots={slots}
        ></vxe-table-column>
      )
    },
  },

  render() {
    const isShow = this.tableColumns.length > 0
    const checkboxconfig = {
      reserve: true,
      highlight: true,
    }
    if (this.checkboxConfig) {
      for (const key in this.checkboxConfig) {
        checkboxconfig[key] = this.checkboxConfig[key]
      }
    }
    return (
      <vxe-table
        ref="vxetable"
        border
        size="mini"
        class="my-table"
        resizable
        sort-config={{
          trigger: 'cell',
          remote: this.serverSort,
          orders: ['desc', 'asc', 'null'],
        }}
        menu-config={this.tableMenu}
        checkbox-config={checkboxconfig}
        data={this.sourceData}
        auto-resize
        sync-resize={this.syncResize()}
        highlight-current-row
        highlight-hover-row
        show-header={this.showHeader}
        onCell-click={this.cellClick}
        show-header-overflow
        show-overflow
        height="100%"
        scroll-x={{ gt: 30 }}
        scroll-y={{ gt: 30, enabled: this.virtualScroll }}
        row-id={this.rowKey}
        empty-text="暂无数据"
        loading={this.loading}
        cell-class-name={this.cellClassName}
        row-class-name={this.rowClassName}
        cell-style={this.cellStyle}
        onCurrent-change={this.currentChange}
        onCheckbox-change={this.checkboxChange}
        onCheckbox-all={this.checkboxAll}
        onResizable-change={this.resizableChange}
        onMenu-click={this.menuClick}
        onToggle-row-expand={this.toggleRowExpand}
        expand-config={this.expandConfig}
        span-method={this.spanMethod}
        onRadio-change={this.radioChange}
        onSort-change={this.sortChange}
        show-footer={this.isFooter}
        footer-method={this.footerMethod}
        footer-span-method={this.footerSpanMethod}
        tree-config={this.treeConfig}
        stripe={this.stripe}
        {...{ props: this.$attrs, on: this.$listeners }}
        key={this.tableKey}
      >
        {isShow && this.selection && (
          <vxe-table-column
            fixed="left"
            field="selection"
            type="checkbox"
            align="center"
            width={
              this.selectMore && this.notSelected ? 120 : 40
            }
            // width="120"
            scopedSlots={{
              title: ({ checked }) =>
                this.selectMore && checked ? (
                  <el-button
                    slot="header"
                    type="text"
                    size="default"
                    onClick={this.selectAll}
                    style={{
                      color: this.more ? 'red' : '#4168FF',
                    }}
                  >
                    {this.more
                      ? `${this.pageSize}+ selected`
                      : `select ${this.pageSize}+`}
                  </el-button>
                ) : null,
            }}
          ></vxe-table-column>
        )}
        {isShow && this.radio && (
          <vxe-table-column
            fixed="left"
            type="radio"
            title=""
            field="radio"
            align="center"
            width="40"
          ></vxe-table-column>
        )}
        {isShow && this.serialNumber && (
          <vxe-table-column
            type="seq"
            title="序号"
            field="num"
            scopedSlots={{
              default: this.$scopedSlots.serialNumberRender,
            }}
            align="center"
            width="60"
          ></vxe-table-column>
        )}

        {this.tableColumns.map((item, index) => {
          if (item.show === false) {
            return null
          }
          if (item.subTitle) {
            return (
              <vxe-table-colgroup
                header-align="center"
                header-class-name="tablecolgroup"
                title={item.label}
              >
                {item.subTitle.map((subitem, index1) => {
                  return this.renderColumn(
                    subitem,
                    index1,
                    'tablecolgroup',
                  )
                })}
              </vxe-table-colgroup>
            )
          } else {
            return this.renderColumn(item, index)
          }
        })}
      </vxe-table>
    )
  },
}
</script>
<style scoped>
.scroller {
  height: 100%;
}

.my-table {
  vertical-align: middle;
}

/* .my-table >>> .vxe-body--column,
.my-table >>> .vxe-header--column.col--ellipsis,
.my-table >>> .vxe-body--column.col--ellipsis,
.my-table >>> .vxe-footer--column.col--ellipsis {
  height: 30px;
} */
.my-table>>>.vxe-checkbox--label {
  padding-left: 0;
}

.my-table>>>.vxe-header--column.tablecolgroup,
.my-table>>>.vxe-header--column.col--ellipsis.tablecolgroup {
  height: 22px !important;
}

.my-table>>>.vxe-cell {
  /* max-height: 30px !important; */
  padding-left: 5px;
  padding-right: 5px;
}

.my-table>>>.green {
  background: green;
  color: #fff;
}
</style>
