<template>
  <div class="el-table"
    :class="[{
      'el-table--fit': fit,
      'el-table--striped': stripe,
      'el-table--border': border || isGroup,
      'el-table--hidden': isHidden,
      'el-table--group': isGroup,
      'el-table--fluid-height': maxHeight,
      'el-table--enable-row-hover': !store.states.isComplex,
      'el-table--enable-row-transition': (store.states.data || []).length !== 0 && (store.states.data || []).length < 100
    }, tableSize ? `el-table--${ tableSize }` : '']"
    @mouseleave="handleMouseLeave($event)">
    <div class="hidden-columns" ref="hiddenColumns"><slot></slot></div>
    <div
      v-if="showHeader"
      class="el-table__header-wrapper"
      ref="headerWrapper">
      <table-header
        ref="tableHeader"
        :store="store"
        :border="border"
        :default-sort="defaultSort"
        >
      </table-header>
    </div>
    <div
      class="el-table__body-wrapper"
      ref="bodyWrapper"
      >
      <table-body
        :context="context"
        :store="store"
        :stripe="stripe"
        :row-class-name="rowClassName"
        :row-style="rowStyle"
        :highlight="highlightCurrentRow"
        >
      </table-body>
      <div
        v-if="!data || data.length === 0"
        class="el-table__empty-block"
        ref="emptyBlock"
        >
        <span class="el-table__empty-text">
          <slot name="empty">{{ emptyText || '暂无数据' }}</slot>
        </span>
      </div>
      <div
        v-if="$slots.append"
        class="el-table__append-wrapper"
        ref="appendWrapper">
        <slot name="append"></slot>
      </div>
    </div>
    <div
      v-if="showSummary"
      v-show="data && data.length > 0"
      class="el-table__footer-wrapper"
      ref="footerWrapper">
      <table-footer
        :store="store"
        :border="border"
        :sum-text="sumText || '合计'"
        :summary-method="summaryMethod"
        :default-sort="defaultSort"
        >
      </table-footer>
    </div>
  </div>
</template>

<script>
import TableStore from 'element-ui/packages/table/src/table-store'
import TableBody from './table-body.js'
import TableHeader from './table-header.js'
import { Loading } from 'element-ui'

let tableIdSeed = 1

export default {
  name: 'ElTable',
  props: {
    data: {
      type: Array,
      default: function() {
        return []
      }
    },

    size: String,

    width: [String, Number],

    height: [String, Number],

    maxHeight: [String, Number],

    fit: {
      type: Boolean,
      default: true
    },

    stripe: Boolean,

    border: Boolean,

    rowKey: [String, Function],

    context: {},

    showHeader: {
      type: Boolean,
      default: true
    },

    showSummary: Boolean,

    sumText: String,

    summaryMethod: Function,

    rowClassName: [String, Function],

    rowStyle: [Object, Function],

    cellClassName: [String, Function],

    cellStyle: [Object, Function],

    headerRowClassName: [String, Function],

    headerRowStyle: [Object, Function],

    headerCellClassName: [String, Function],

    headerCellStyle: [Object, Function],

    highlightCurrentRow: Boolean,

    currentRowKey: [String, Number],

    emptyText: String,

    expandRowKeys: Array,

    defaultExpandAll: Boolean,

    defaultSort: Object,

    tooltipEffect: String,

    spanMethod: Function,

    selectOnIndeterminate: {
      type: Boolean,
      default: true
    },
    dataReadUrl: {
      type: [String, Function],
      default: ''
    },
    autoGetData: {
      type: Boolean,
      default: true
    },
    currentPage: {
      type: Number,
      default: 1
    }
  },

  components: {
    TableHeader,
    TableBody
  },

  methods: {
    getMigratingConfig() {
      return {
        events: {
          expand: 'expand is renamed to expand-change'
        }
      }
    },

    setCurrentRow(row) {
      this.store.commit('setCurrentRow', row)
    },

    toggleRowSelection(row, selected) {
      this.store.toggleRowSelection(row, selected)
      this.store.updateAllSelected()
    },

    toggleRowExpansion(row, expanded) {
      this.store.toggleRowExpansion(row, expanded)
    },

    clearSelection() {
      this.store.clearSelection()
    },

    clearFilter() {
      this.store.clearFilter()
    },

    clearSort() {
      this.store.clearSort()
    },

    handleMouseLeave() {
      this.store.commit('setHoverRow', null)
      if (this.hoverState) this.hoverState = null
    },
    updateScrollY() {
      // 这个方法会被 table-store.js 调用
      // 但这个精简版表格不需要，去掉布局相关的方法
    },
    bindEvents() {
      const { headerWrapper, footerWrapper } = this.$refs
      let self = this

      this.bodyWrapper.addEventListener('scroll', function() {
        if (headerWrapper) headerWrapper.scrollLeft = this.scrollLeft
        if (footerWrapper) footerWrapper.scrollLeft = this.scrollLeft
        const maxScrollLeftPosition = this.scrollWidth - this.offsetWidth - 1
        const scrollLeft = this.scrollLeft
        if (scrollLeft >= maxScrollLeftPosition) {
          self.scrollPosition = 'right'
        } else if (scrollLeft === 0) {
          self.scrollPosition = 'left'
        } else {
          self.scrollPosition = 'middle'
        }
      })
    },
    getData (pageIndex) {
      if (!pageIndex) {
        this.tmpCurrentPage = 1
      }
      return new Promise(async (resolve, reject) => {
        const self = this
        let loadingInstance = Loading.service({ target: self.$el })
        let readUrl
        let options
        try {
          if (typeof this.dataReadUrl === 'string') {
            readUrl = this.dataReadUrl
            options = {
              params: {
                pageIndex: this.tmpCurrentPage,
                pageSize: this.tmpPageSize
              }
            }
          } else if (typeof this.dataReadUrl === 'function') {
            const result = this.dataReadUrl()
            readUrl = result[0]
            options = result[1]
            options.params = options.params || {}
            options.params.pageIndex = this.tmpCurrentPage
            options.params.pageSize = this.tmpPageSize
          }
          options.params.pageSize = !options.params.pageSize ? 15 : options.params.pageSize
          options.params.pageIndex--
          let res = await axios.get(readUrl, options)
          if (res.data.status === 0) {
            self.total = 0
            self.data.splice(0, self.data.length)
            loadingInstance.close()
            reject(res.data.message || `从接口${this.dataReadUrl}获取数据失败 ！`)
          }
          if (!res.data.total && res.data.data) {
            if (res.data.total === 0) {
              self.total = res.data.total
            } else if (res.data.data.length > 0 && this.pageSize) {
              reject(new Error('接口 ' + this.dataReadUrl + ' 没有返回 total ，无法设置数据表格的总记录数！'))
            }
          } else {
            self.total = res.data.total
          }
          if (!Array.isArray(res.data.data)) {
            self.total = 0
            self.data.splice(0, self.data.length)
            reject(new Error('接口 ' + this.dataReadUrl + ' 没有返回 data ，无法设置数据表格的数据！'))
          } else {
            self.data.splice.apply(self.data, [0, self.data.length].concat(res.data.data))
            self.afterSortData = [...self.data]
          }
          this.$nextTick(() => {
            loadingInstance.close()
          })
          resolve()
        } catch (e) {
          loadingInstance.close()
        }
      })
    }
  },

  created() {
    this.tableId = 'el-table_' + tableIdSeed++
  },

  computed: {
    tableSize() {
      return this.size || (this.$ELEMENT || {}).size
    },

    bodyWrapper() {
      return this.$refs.bodyWrapper
    },

    shouldUpdateHeight() {
      return this.height ||
        this.maxHeight
    },

    selection() {
      return this.store.states.selection
    },

    columns() {
      return this.store.states.columns
    },

    tableData() {
      return this.store.states.data
    }
  },

  watch: {
    currentRowKey(newVal) {
      this.store.setCurrentRowKey(newVal)
    },

    data: {
      immediate: true,
      handler(value) {
        this.store.commit('setData', value)
      }
    },

    expandRowKeys: {
      immediate: true,
      handler(newVal) {
        if (newVal) {
          this.store.setExpandRowKeys(newVal)
        }
      }
    }
  },

  destroyed() {
  },

  mounted() {
    this.$nextTick(() => {
      if (this.dataReadUrl && this.autoGetData) {
        // 当存在dataReadUrl时，从url获取数据，并更新data
        this.getData(this.tmpCurrentPage)
      }
    })

    this.bindEvents()
    this.store.updateColumns()

    // init filters
    this.store.states.columns.forEach(column => {
      if (column.filteredValue && column.filteredValue.length) {
        this.store.commit('filterChange', {
          column,
          values: column.filteredValue,
          silent: true
        })
      }
    })

    this.$ready = true
  },

  data() {
    let tmpCurrentPage = this.currentPage || 1
    const store = new TableStore(this, {
      rowKey: this.rowKey,
      defaultExpandAll: this.defaultExpandAll,
      selectOnIndeterminate: this.selectOnIndeterminate
    })
    return {
      store,
      isHidden: false,
      renderExpanded: null,
      // 是否拥有多级表头
      isGroup: false,
      scrollPosition: 'left',
      tmpCurrentPage: tmpCurrentPage
    }
  }
}
</script>
