<template>
  <div
    class="bi-table"
    :class="{'bi-table__loading':loading}"
  >
    <div class="bi-table-wrapper">
      <el-table
        ref="elTable"
        v-loading="loading"
        v-sticky-header="{offsetTop:stickyTop}"
        v-sticky-footer="{offsetBottom:stickyBottom}"
        :data="data"
        :max-height="maxHeight"
        v-bind="$attrs"
        v-on="$listeners"
        @header-dblclick="handleHeaderClick"
      >
        <template v-for="item in tbColumns">
          <el-table-column
            v-if="item.slotScope&&item.slotScopeHeader"
            :key="'a'+item.prop + item.label"
            v-bind="item"
            v-on="$listeners"
          >
            <template #default="scope">
              <slot
                :name="item.prop"
                v-bind="scope"
              ></slot>
            </template>
            <template v-slot:header>
              <slot :name="item.prop+'_header'"></slot>
              <BiTableHeaderPopper :prop="item.prop" />
            </template>
          </el-table-column>
          <el-table-column
            v-else-if="item.slotScope&&!item.slotScopeHeader"
            :key="'b'+item.prop + item.label"
            v-bind="item"
            v-on="$listeners"
          >
            <template v-slot:header="scope">
              <BiRender
                v-if="item.headerRender"
                :scope="scope"
                :render="item.headerRender"
              />
              <span v-else>{{ item.label }}</span>
              <BiTableHeaderPopper :prop="item.prop" />
            </template>
            <template #default="scope">
              <slot
                :name="item.prop"
                v-bind="scope"
              ></slot>
            </template>
          </el-table-column>
          <el-table-column
            v-else-if="!item.slotScope&&item.slotScopeHeader&&item.render"
            :key="'c'+item.prop + item.label"
            v-bind="item"
            v-on="$listeners"
          >
            <template v-slot:header>
              <slot :name="item.prop+'_header'"></slot>
              <BiTableHeaderPopper :prop="item.prop" />
            </template>
            <template #default="scope">
              <BiRender
                v-if="item.render"
                :scope="scope"
                :render="item.render"
              />
            </template>
          </el-table-column>
          <bi-column-group
            v-else-if="item.children"
            :key="'g'+item.prop + item.label + '1'"
            v-bind="$attrs"
            :column="item"
          />
          <bi-column
            v-else
            :key="'d'+item.prop + item.label + '1'"
            v-bind="$attrs"
            :column="item"
          />
        </template>
      </el-table>
    </div>
    <template v-if="pagination">
      <pagination
        v-if="data.length > 0"
        v-bind="$attrs"
        :disabled="loading"
        v-on="$listeners"
      />
    </template>
    <BiTableHeaderEdit ref="BiTableHeaderEdit" />
  </div>
</template>

<script>
import BiColumn from './columu'
import BiColumnGroup from './columuGroup.vue'
import BiRender from './render.vue'
import Pagination from '../../Pagination/src'
import BiTableHeaderPopperJs from '../../TableHeaderPopper/src/popper'
import BiTableHeaderEdit from '../../TableHeaderPopper/src/EditBox.vue'
import BiTableHeaderPopper from '../../TableHeaderPopper'
export default {
  name: 'BiTable',
  components: {
    Pagination,
    BiRender,
    BiColumn,
    BiColumnGroup,
    BiTableHeaderEdit,
    BiTableHeaderPopper
  },
  props: {
    data: {
      type: Array,
      default: () => {
        return []
      }
    },
    column: {
      type: Array,
      default: () => {
        return []
      }
    },
    columnsProps: {
      type: Object,
      default: () => {
        return {}
      }
    },
    loading: {
      type: Boolean,
      default: false
    },
    pagination: {
      type: Boolean,
      default: false
    },
    fixed: {
      type: String,
      default: ''
    },
    fixedOffset: {
      type: [String, Number],
      default: ''
    },
    stickyTop: {
      type: [Number, String],
      default: 50
    },
    stickyBottom: {
      type: Number,
      default: 0
    },
    headerPopperType: {
      type: String,
      default: ''
    }
  },
  provide() {
    return {
      biTable: this
    }
  },
  data() {
    return {
      maxHeight: null,
      headerStatus: false,
      footerStatus: false,
      headerPopper: new BiTableHeaderPopperJs(this.headerPopperType)
    }
  },
  computed: {
    tbColumns() {
      const { column, columnsProps: props } = this
      return column.map((col) => {
        const newColumn = this.formatColumn(col)
        const it = Object.assign({}, props, newColumn)
        return it
      })
    },
    fixedHeader() {
      return this.fixed
    }
  },
  methods: {
    resetHeaderFooter() {
      if (this.fixedHeader === 'sticky') {
        this.handleStickyHeader()
        if (Object.prototype.hasOwnProperty.call(this.$attrs, 'show-summary')) {
          this.handleStickyFooter()
        }
      } else if (this.fixedHeader === 'fullscreen') {
        this.handleFixedHeader()
        // this.maxHeight = 300
      }
    },
    handleStickyHeader() {
      const fixedOffset = Number(this.fixedOffset)
      // 获取滚动条滚动的高度
      const tableToClientTop = this.$el.getBoundingClientRect().top

      let top = 0
      this.$el.getElementsByClassName('el-table__header-wrapper')[0].style.transform = `translate(0px, ${0}px)`
      this.$el.getElementsByClassName('el-table__header-wrapper')[0].style.position = 'relative'

      if (tableToClientTop < fixedOffset && tableToClientTop >= 0) {
        top = fixedOffset - tableToClientTop - 1
      } else if (tableToClientTop < 0) {
        top = Math.abs(tableToClientTop) + fixedOffset - 1
      } else {
        top = 0
      }

      if (top) {
        // 判断当前是否已经固定。headerStatus优化值 可有可无。
        if (!this.headerStatus) {
          this.headerStatus = true
          // 当前子盒子要在父盒子中横向滚动 所以使用absolute 绝对定位。
          this.$el.getElementsByClassName('el-table__header-wrapper')[0].style.position = 'absolute'
          this.$el.getElementsByClassName('el-table__header-wrapper')[0].style.zIndex = '2'
        }
        // 绝对定位 top值需要一直改变 所以动态添加top值

        // 中间header
        this.$el.getElementsByClassName('el-table__header-wrapper')[0].style.transform = `translate(0px, ${top}px)`
        this.$el.getElementsByClassName('el-table__header-wrapper')[0].style.position = 'relative'

        // 左边header
        if (this.$el.querySelector('.el-table__fixed')) {
          this.$el.querySelector('.el-table__fixed').style.zIndex = '3'
        }
        if (this.$el.querySelector('.el-table__fixed .el-table__fixed-header-wrapper')) {
          this.$el.querySelector('.el-table__fixed .el-table__fixed-header-wrapper').style.transform = `translate(0px, ${top}px)`
          this.$el.querySelector('.el-table__fixed .el-table__fixed-header-wrapper').style.zIndex = '4'
        }

        // 右边header
        if (this.$el.querySelector('.el-table__fixed-right')) {
          this.$el.querySelector('.el-table__fixed-right').style.zIndex = '4'
        }
        if (this.$el.querySelector('.el-table__fixed-right .el-table__fixed-header-wrapper')) {
          this.$el.querySelector('.el-table__fixed-right .el-table__fixed-header-wrapper').style.transform = `translate(0px, ${top}px)`
          this.$el.querySelector('.el-table__fixed-right .el-table__fixed-header-wrapper').style.zIndex = '4'
        }
      } else {
        this.headerStatus = false
        this.$el.getElementsByClassName('el-table__header-wrapper')[0].style.position = 'relative'
        this.$el.getElementsByClassName('el-table__header-wrapper')[0].style.transform = `translate(0px, 0px)`

        if (this.$el.querySelector('.el-table__fixed .el-table__fixed-header-wrapper')) {
          this.$el.querySelector('.el-table__fixed .el-table__fixed-header-wrapper').style.zIndex = `5`
          this.$el.querySelector('.el-table__fixed .el-table__fixed-header-wrapper').style.transform = `translate(0px, 0px)`
        }
        if (this.$el.querySelector('.el-table__fixed-right .el-table__fixed-header-wrapper')) {
          this.$el.querySelector('.el-table__fixed-right .el-table__fixed-header-wrapper').style.zIndex = `5`
          this.$el.querySelector('.el-table__fixed-right .el-table__fixed-header-wrapper').style.transform = `translate(0px, 0px)`
        }
        this.$el.getElementsByClassName('el-table__header-wrapper')[0].style.zIndex = '3'
        this.$el.getElementsByClassName('el-table__body-wrapper')[0].style.paddingTop = '0'
      }
    },
    handleStickyFooter() {
      const clientHeight = document.documentElement.clientHeight
      // // 获取滚动条滚动的高度
      const tableHeight = this.$el.querySelector('.bi-table-wrapper').clientHeight
      const tableToClientTop = this.$el.getBoundingClientRect().top

      const top = -tableHeight + (clientHeight - tableToClientTop)
      if (Math.abs(tableToClientTop) + clientHeight < tableHeight || top < 0) {
        // 判断当前是否已经固定。headerStatus优化值 可有可无。
        if (!this.footerStatus) {
          this.footerStatus = true
          // 当前子盒子要在父盒子中横向滚动 所以使用absolute 绝对定位。
          this.$el.getElementsByClassName('el-table__footer-wrapper')[0].style.position = 'absolute'
          this.$el.getElementsByClassName('el-table__footer-wrapper')[0].style.zIndex = '2'
        }
        // 绝对定位 top值需要一直改变 所以动态添加top值

        // 中间footer
        this.$el.getElementsByClassName('el-table__footer-wrapper')[0].style.transform = `translate(0px, ${top}px)`
        this.$el.getElementsByClassName('el-table__footer-wrapper')[0].style.position = 'relative'

        // 左边footer
        if (this.$el.querySelector('.el-table__fixed')) {
          this.$el.querySelector('.el-table__fixed').style.zIndex = '3'
        }
        if (this.$el.querySelector('.el-table__fixed .el-table__fixed-footer-wrapper')) {
          this.$el.querySelector('.el-table__fixed .el-table__fixed-footer-wrapper').style.transform = `translate(0px, ${top}px)`
          this.$el.querySelector('.el-table__fixed .el-table__fixed-footer-wrapper').style.zIndex = '4'
        }

        // 右边footer
        if (this.$el.querySelector('.el-table__fixed-right')) {
          this.$el.querySelector('.el-table__fixed-right').style.zIndex = '4'
        }
        if (this.$el.querySelector('.el-table__fixed-right .el-table__fixed-footer-wrapper')) {
          this.$el.querySelector('.el-table__fixed-right .el-table__fixed-footer-wrapper').style.transform = `translate(0px, ${top}px)`
          this.$el.querySelector('.el-table__fixed-right .el-table__fixed-footer-wrapper').style.zIndex = '4'
        }
      } else {
        this.footerStatus = false
        this.$el.getElementsByClassName('el-table__footer-wrapper')[0].style.position = 'relative'
        this.$el.getElementsByClassName('el-table__footer-wrapper')[0].style.transform = `translate(0px, 0px)`

        if (this.$el.querySelector('.el-table__fixed .el-table__fixed-footer-wrapper')) {
          this.$el.querySelector('.el-table__fixed .el-table__fixed-footer-wrapper').style.zIndex = `4`
          this.$el.querySelector('.el-table__fixed .el-table__fixed-footer-wrapper').style.transform = `translate(0px, 0px)`
        }
        if (this.$el.querySelector('.el-table__fixed-right .el-table__fixed-footer-wrapper')) {
          this.$el.querySelector('.el-table__fixed-right .el-table__fixed-footer-wrapper').style.zIndex = `4`
          this.$el.querySelector('.el-table__fixed-right .el-table__fixed-footer-wrapper').style.transform = `translate(0px, 0px)`
        }
        this.$el.getElementsByClassName('el-table__footer-wrapper')[0].style.zIndex = '3'
        this.$el.getElementsByClassName('el-table__body-wrapper')[0].style.paddingTop = '0'
      }
    },
    resetStickyFooter() {
      this.footerStatus = false
      this.$el.getElementsByClassName('el-table__footer-wrapper')[0].style.position = 'relative'
      this.$el.getElementsByClassName('el-table__footer-wrapper')[0].style.transform = `translate(0px, 0px)`

      if (this.$el.querySelector('.el-table__fixed .el-table__fixed-footer-wrapper')) {
        this.$el.querySelector('.el-table__fixed .el-table__fixed-footer-wrapper').style.zIndex = `4`
        this.$el.querySelector('.el-table__fixed .el-table__fixed-footer-wrapper').style.transform = `translate(0px, 0px)`
      }
      if (this.$el.querySelector('.el-table__fixed-right .el-table__fixed-footer-wrapper')) {
        this.$el.querySelector('.el-table__fixed-right .el-table__fixed-footer-wrapper').style.zIndex = `4`
        this.$el.querySelector('.el-table__fixed-right .el-table__fixed-footer-wrapper').style.transform = `translate(0px, 0px)`
      }
      this.$el.getElementsByClassName('el-table__footer-wrapper')[0].style.zIndex = '3'
      this.$el.getElementsByClassName('el-table__body-wrapper')[0].style.paddingTop = '0'
    },
    handleFixedHeader() {
      const offsetTop = this.$el.getBoundingClientRect().top // el-table 父级div
      const tableHeight = window.innerHeight - Number(this.fixedOffset) - (this.pagination ? 72 : 0)
      if (Math.abs(tableHeight - this.maxHeight) > 3) {
        this.maxHeight = tableHeight
      }
      if (offsetTop <= Number(this.fixedOffset) + 20 && offsetTop >= 0) {
        this.$el.querySelector('.bi-table-wrapper>.el-table>.el-table__body-wrapper').style.overflowY = 'auto' // el-table class
      } else {
        this.$el.querySelector('.bi-table-wrapper>.el-table>.el-table__body-wrapper').style.overflowY = 'hidden' // el-table class
      }
    },
    getElementTop(element) {
      if (!element) {
        return 0
      }
      let actualTop = element.offsetTop
      let current = element.offsetParent

      while (current !== null) {
        actualTop += current.offsetTop
        current = current.offsetParent
      }
      return actualTop
    },
    formatColumn(columnData) {
      const column = Object.assign({}, columnData)
      if (typeof column.width === 'function') {
        column.width = column.width()
      }
      if (typeof column.minWidth === 'function') {
        column.minWidth = column.minWidth()
      }
      if (column.renderHeader) {
        column.headerRender = column.renderHeader
        // column.renderHeader = column.headerRender
        delete column.renderHeader
      }
      if (column.children) {
        column.children = column.children.map((item) => {
          return this.formatColumn(item)
        })
      }
      return column
    },
    handleHeaderClick(column, event) {
      event.preventDefault()
      this.$refs.BiTableHeaderEdit && this.$refs.BiTableHeaderEdit && this.headerPopper && this.headerPopper.editEnabled && column.property && this.$refs.BiTableHeaderEdit.show(column.property)
    }
  }
}
</script>

<style lang="scss">
.el-main {
  overflow: visible;
  overflow: clip;
}
</style>
