<template>
  <div class="merge-table" v-bind="$attrs" v-on="$listeners">
    <table class="table table-bordered el-table el-table--fit el-table--scrollable-x el-table--enable-row-hover el-table--enable-row-transition">
      <thead class="is-group has-gutter">
        <tr v-for="(row, index) in tableHeader" :key="index">
          <th
            v-for="(cell, i) in row"
            :key="i"
            :rowspan="cell.rowspan"
            :colspan="cell.colspan"
            class="el-head-cell"
          >{{ cell.text }}</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(row, index) in rows" :key="index" class="el-table__row">
          <td
            v-for="(td, idx) in row"
            :key="idx"
            :colspan="td.colSpan"
            :rowspan="td.rowSpan"
            class="el-table__cell"
          >
            <slot
              name="td"
              v-bind="{row, rowIdx: index, td, tdIdx: idx}"
            />
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
import Tree from './Tree'
import { debounce } from '@/utils'
/**
 * 合并表格组件
 * 专注于树结构与合并表格之间的转换
 * @example ./MergeTable.md
 * @displayName MergeTable
 */
export default {
  name: 'MergeTable',
  model: {
    prop: 'treeData',
    event: 'update'
  },
  props: {
    /**
     * 树数据，以children为子节点属性名，id为索引
     * @model
     */
    treeData: {
      type: Object,
      required: true,
      default: () => ({})
    },
    tableHeader: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      rows: []
    }
  },
  watch: {
    treeData: {
      deep: true,
      handler() {
        this.compile()
      }
    }
  },
  mounted() {
    this.compile()
  },
  methods: {
    /**
     * 根据id获取节点数据
     * @param {string | Number} nodeId
     * @public
     */
    GetNodeById(nodeId) {
      return Tree.getNodeById(this.treeData, nodeId)
    },
    /**
     * 根据id获取父节点数据
     * @param {string | Number} nodeId
     * @public
     */
    GetParentByChildId(nodeId) {
      return Tree.getParentByChildId(this.treeData, nodeId, this.treeData)
    },
    /**
     * 删除某节点
     * @param {string | Number} nodeId
     * @public
     */
    RemoveNode(nodeId) {
      const parent = Tree.getParentByChildId(
        this.treeData,
        nodeId,
        this.treeData
      )
      const index = parent.children.findIndex(item => item.id === nodeId)
      parent.children.splice(index, 1)
      this.$emit('update', this.treeData)
    },
    /**
     * 往id下添加一个子节点
     * @param {string | Number} nodeId
     * @param {Object} value
     * @public
     */
    AddChild(nodeId, value = {}) {
      const parent = Tree.getNodeById(this.treeData, nodeId)

      const children = parent.children || []
      // const id = uuidv4()
      const id = Math.random().toString(36).substr(2, 9)

      children.push({
        id,
        parentId: nodeId,
        ...value
      })
      this.$set(parent, 'children', children)
    },
    /**
     * 转换tree转换后的数组
     * @public
     */
    GetRows() {
      return this.rows
    },
    /**
     * 改变节点数据
     * @param {string | Number} key 节点属性
     * @param {Object} value 节点值
     * @param {string | Number} nodeId 节点id
     * @public
     */
    ChangeNode(key, value, nodeId) {
      const data = Tree.getNodeById(this.treeData, nodeId)
      this.$set(data, key, value)
    },

    compile: debounce(function() {
      const rows = Tree.translate2Rows(this.treeData)
      this.rows = rows
    }, 50),
    refresh() {
      this.rows = Tree.translate2Rows(this.treeData)
    }
  }
}
</script>

<style lang="less" scoped>
.merge-table {
  table {
    border-spacing: 0;
    border-collapse: collapse;
  }
  td {
    border: 1px solid;
    height: 28px;
    padding: 0 0 0 4px;
  }
  .table-bordered > thead > tr > th,
  .table-bordered > tbody > tr > th,
  .table-bordered > tfoot > tr > th,
  .table-bordered > thead > tr > td,
  .table-bordered > tbody > tr > td,
  .table-bordered > tfoot > tr > td {
    border-color: #d2d6de;
  }
  table thead th.el-head-cell {
    border: 1px solid;
    background-color: #F5F7FA;
    padding: 0 4px;
    height: 28px;
    border-color:#d2d6de;
    //border-top:1px solid #d2d6de;
    //border-left:1px solid #d2d6de;
  }
}
</style>
