<template>
  <div id="RenderTable-container">
    <el-form :model="model" ref="model">
      <el-table
        :class="drag ? 'dragTable' : ''"
        :data="model.data"
        row-key="id"
        lazy
        @sort-change="sortChange"
        ref="renderTable"
        :border="border"
        stripe
        :header-align="align"
        size="small"
        default-expand-all
        :max-height="maxHeight || null"
        @selection-change="handleSelectionChange"
        @row-click="handleRowClick"
        :tree-props="{ children: 'childList' }"
      >
        <template v-for="(item, index) in columns">
          <!--没有type 的模板-->
          <el-table-column
            :align="item.align"
            :row-key="item.id"
            :label="item.key"
            :type="item.type"
            :sortable="item.sortable"
            :key="index"
            :min-width="item.width ? item.width : 225"
            :fixed="item.fixed"
            v-if="!item.type"
          >
            <template #header="scope" v-if="item.headRender">
              <header-slot :item="item" :scope="scope" />
            </template>
            <template #default="scope">
              <!--表单校验-->
              <el-form-item v-if="item.ruleCode" :prop="'data.' + scope.$index + '.' + item.ruleCode" :rules="item.ruleCode ? item.rules : []">
                <body-slot :item="item" :scope="scope" v-if="item.render" />
              </el-form-item>
              <body-slot :item="item" :scope="scope" v-if="!item.ruleCode && item.render" />
              <!--自定义render模板-->
              <!--</el-form>-->
              <!--自带的btn 不能有prop 属性-->
              <div v-if="!item.selfBtn && !item.prop && !item.type && !item.render" :fixed="item.fixed ? item.fixed : fixed">
                <el-button type="primary" size="mini" plain :disabled="disabled" @click="edit(scope.row, scope.$index)">编辑</el-button>
                <el-button type="danger" size="mini" plain :disabled="disabled" @click="del(scope.row, scope.$index)">删除</el-button>
              </div>
              <!--如果渲染的是selfBtn-->
              <div v-if="item.selfBtn && !item.render">
                <el-button
                  v-for="(btn, btnIndex) in item.selfBtn"
                  :fixed="item.fixed ? item.fixed : fixed"
                  :disabled="item.disabled !== undefined ? item.disabled : disabled"
                  :type="btn.type ? btn.type : 'primary'"
                  :size="btn.size ? btn.size : 'mini'"
                  :key="btnIndex"
                  @click="handlerMethods(scope.row, scope.$index, btn)"
                  :label="btn.name"
                >
                  {{ btn.name }}
                </el-button>
              </div>
              <!--提示框 内部判断是否给单元格提示-->
              <TooltipScope :scope="scope" :item="item" v-if="!item.type && !item.render && item.prop" />
            </template>
          </el-table-column>
          <!--有设置type 的表格  type 设置的是selection 和 index-->
          <el-table-column
            :key="index"
            :row-key="item.id"
            :align="align"
            :label="item.key"
            :type="item.type"
            :width="item.width"
            v-else-if="item.type === 'index' || item.type === 'selection'"
          />
          <el-table-column
            :key="index"
            :row-key="item.id"
            :align="align"
            :label="item.key"
            :type="item.type"
            :width="item.width"
            v-else-if="item.type === 'radio'"
          >
            <template #default="scope">
              <el-radio v-model="check" :label="scope.$index" @change="setCheck($event, scope)">{{ null }}</el-radio>
            </template>
          </el-table-column>
        </template>
        <!--自定义默认按钮  ps:增加 一行   删除一行-->
        <el-table-column v-if="deletion" :align="align" width="180" :fixed="fixed">
          <template slot-scope="scope">
            <div>
              <el-button
                type="primary"
                plain
                @click="
                  e => {
                    addRow(scope.row, scope.$index)
                  }
                "
                :disabled="disabled"
                circle
                icon="el-icon-plus"
                size="medium"
                class="tableBtn"
              />
              <el-button
                type="danger"
                plain
                @click="
                  e => {
                    delRow(scope.row, scope.$index)
                  }
                "
                :disabled="disabled"
                circle
                size="medium"
                icon="el-icon-minus"
                class="tableBtn"
              />
            </div>
          </template>
        </el-table-column>
      </el-table>
    </el-form>
    <!--表格分页-->
    <div class="text-right" v-if="total">
      <el-pagination
        class="table-container"
        @size-change="sizeChange"
        @current-change="currentChange"
        background
        :currentPage="currentPage"
        layout="prev,sizes, pager, next,jumper"
        :page-sizes="[10, 20, 30, 40, 50]"
        :total="total"
      />
    </div>
  </div>
</template>

<script>
import Sortable from 'sortablejs'
import TooltipScope from './component/TooltipScope'
import bodySlot from './component/bodySlot'
import HeaderSlot from './component/headerSlot'
/* * @Author: 陈昱达 * @Date: 2020-08-27 17:40:39 * @Last Modified by: 陈昱达 * @Last Modified time: 2020-08-27 17:40:39 */
export default {
  name: 'RenderTable',
  data() {
    return {
      fixed: 'right',
      check: ''
    }
  },
  computed: {
    model(v) {
      return {
        data: v.data
      }
    }
  },
  components: { HeaderSlot, TooltipScope, bodySlot },
  props: {
    //是否拖拽
    drag: {
      type: Boolean,
      default: false
    },
    //是否只能选择一条数据
    isSelectOnly: {
      type: Boolean,
      default: false
    },
    //是否展示 删减行 按钮 和新增行按钮
    deletion: {
      type: Boolean,
      default: true
    },
    //页码
    currentPage: {
      type: Number
    },
    //是否禁用表格自带按钮
    disabled: {
      type: Boolean,
      default: false
    },
    //表格边框 border
    border: {
      type: Boolean,
      default: true
    },
    // 是否剧中 align
    align: {
      type: String,
      default: 'center'
    },
    // table data
    data: {
      type: Array
    },
    //columns
    columns: {
      type: Array
    },
    //total
    total: {
      type: Number
    },
    maxHeight: {
      type: String
    }
  },
  mounted() {
    if (this.drag) {
      this.rowDrop()
      // this.columnDrop()
    }
  },
  methods: {
    // 单选选中
    setCheck(e, scope) {
      this.check = e
      this.$emit('selectRow', { row: scope.row, index: scope.$index })
      this.$emit('select-row', { row: scope.row, index: scope.$index })
    },
    sortChange(sortData) {
      let filters = this.columns.filter(item => item.key === sortData.column.label)
      if (filters && filters.length > 0) {
        sortData.prop = filters[0].prop
      }
      this.$emit('sortChange', sortData)
      this.$emit('sort-change', sortData)
    },
    //行拖拽
    rowDrop() {
      const tbody = document.querySelector('.dragTable .el-table__body-wrapper tbody')
      Sortable.create(tbody, {
        animation: 180,
        onEnd: ({ newIndex, oldIndex }) => {
          const currRow = this.data.splice(oldIndex, 1)[0]
          this.data.splice(newIndex, 0, currRow)
        }
      })
    },
    //列拖拽  目前有问题 暂未解决
    columnDrop() {
      const wrapperTr = document.querySelector('.dragTable .el-table__header-wrapper tr')
      Sortable.create(wrapperTr, {
        animation: 180,
        filter: '.el-table-column--selection',
        delay: 0,
        onEnd: evt => {
          const oldItem = this.columns[evt.oldIndex]
          this.columns.splice(evt.oldIndex, 1)
          this.columns.splice(evt.newIndex, 0, oldItem)
        }
      })
    },
    //edit in table
    edit(row, index) {
      this.$emit('edit', row, index)
    },
    // del In Table
    del(row, index) {
      this.$emit('del', row, index)
    },
    //展示条数改变
    sizeChange(size) {
      this.$emit('sizeChange', size)
      this.$emit('size-change', size)
    },
    //页码改变
    currentChange(current) {
      this.$emit('currentChange', current)
      this.$emit('current-change', current)
    },
    //根据数据的格式去返回对应的数据结构
    getDataType(type) {
      let dataType = ''
      if (type === '[object Array]') {
        dataType = []
      } else if (type === '[object Object]') {
        dataType = {}
      }
      return dataType
    },
    //Add a new line
    addRow(row, index) {
      let newRow = JSON.parse(JSON.stringify(row))
      for (let item in newRow) {
        newRow[item] = this.getDataType(Object.prototype.toString.call(newRow[item]))
      }
      this.data.splice(index + 1, 0, newRow)
      this.$emit('buttonAdd', row, newRow)
      this.$emit('button-add', row, newRow)
    },
    //Delete row
    delRow(row, index) {
      this.$emit('buttonDel', row, index)
      this.$emit('button-del', row, index)
      let newRow = JSON.parse(JSON.stringify(row))
      this.data.splice(index, 1)
      if (this.data.length === 0) {
        for (let item in newRow) {
          newRow[item] = this.getDataType(Object.prototype.toString.call(newRow[item]))
        }
        this.data.push(newRow)
      }
    },
    //btnSelf 把当前数据提交给父组件自定义method事件中
    handlerMethods(row, index, btn) {
      this.$emit(btn.method, { row, index })
    },

    handleRowClick(row, column, event) {
      this.$emit('row-click', row, column, event)
    },
    handleSelectionChange(row) {
      if (this.isSelectOnly && row.length > 1) {
        // 如果只能选择一条数据，且当前选择超过一条，则只保留最后选择的一条
        const lastRow = row[row.length - 1]
        this.$refs.renderTable.clearSelection()
        this.$nextTick(() => {
          this.$refs.renderTable.toggleRowSelection(lastRow, true)
        })
        this.$emit('selection-change', [lastRow])
      } else {
        this.$emit('selection-change', row)
      }
    },
    //具体查看element 文档
    toggleRowSelection(rows) {
      this.$nextTick(() => {
        if (rows) {
          rows.forEach(row => {
            this.$refs.renderTable.toggleRowSelection(row)
          })
        } else {
          this.$refs.multipleTable.clearSelection()
        }
      })
    },
    clearSelection() {
      this.$nextTick(() => {
        this.$refs.renderTable.clearSelection()
      })
    }
  }
}
</script>

<style scoped lang="scss">
.pd5 {
  padding-left: 5px;
}

.tableBtn {
  padding: 5px;
}

/deep/.el-table {
  .el-radio__label {
    padding: unset;
  }
  .el-form-item__error {
    position: unset;
  }
  .el-form-item__content {
    line-height: unset;
  }
  .el-form-item__error {
    position: unset;
  }
  .el-form-item {
    margin: 0;
  }
}
</style>
