<template>
  <div>
    <slot name="header">
      <el-button v-if="moduleProp?.showAddBtn" class="btn" plain type="primary" @click="handlerAdd">新增</el-button>
    </slot>

    <ed-table :columns="columns" :data="tableData" :loading="initLoading" :pagination="false" v-bind="tableProps">
      <!-- 表格列插槽 -->
      <template v-for="name in slotNames" v-slot:[name]="scope">
        <slot :name="name" v-bind="scope"></slot>
      </template>


      <template v-if="moduleProp?.showAction" v-slot:operate="{row, $index}">
        <slot name="operate" v-bind="{row, $index}">
          <el-button size="mini" type="text" @click="handlerEdit(row, $index)">编辑</el-button>
          <el-divider direction='vertical'></el-divider>
          <el-popconfirm title="确定删除数据吗？" @confirm="handlerDelete(row, $index)">
            <el-button slot="reference" size="mini" style="color: red" type="text">删除</el-button>
          </el-popconfirm>
        </slot>
      </template>
    </ed-table>

    <!--  编辑  -->
    <ed-drawer ref="elsDrawer" :title="drawerTit" :visible="visible" @close="handlerClose" @ok="handlerOk">
      <easy-data-form ref="easyDataForm" :control-config="edFormConfig" :form-data="edFormData"></easy-data-form>
    </ed-drawer>
  </div>
</template>

<script>
import EasyDataMixins              from '../mixins/EasyDataMixins'
import {getPath, getVarType}       from "../../utils/utils";
import {setFormData, setTableData} from "../../utils/useBusiness";
import {TempType}                  from "../../api/easyData";

/**
 * EasyDataTable组件
 * - 示例
 *
 * ```vue
 * <easy-data-table ref="EasyDataTable" :columnType="columnType" :dataSourceName="dataSourceName" :viewId="viewId">
 * </easy-data-table>
 * ```
 * 详细用法参考下方链接
 *
 * [EasyDataTable组件使用示例](./web-comp/ExampleEasyDataTableCode.md)
 *
 * 混入属性参考
 *
 * [EasyDataMixins](./EasyDataMixins.md)
 */
export default {
  name: "EasyDataTable",
  mixins: [EasyDataMixins],
  data() {
    return {
      tableData: [],
      columns: [],
      visible: false,
      drawerTit: '',
      cacheIndex: null,
      edFormData: {},
      edFormConfig: {},
      // 插槽名
      slotNames: []
    }
  },
  props: {
    /**
     * Table 表格props(参考[EdTable](web-comp/new/Table.md?id=dtable-props)组件)
     * @default {}
     */
    tableProps: {
      type: Object,
      default: () => {
      }
    },

    // 数据源配置信息
    controlConfig: {
      type: Object,
      default: () => {
      }
    }
  },
  watch: {
    controlConfig: {
      handler(newVal, oldVal) {
        if (newVal && Object.keys(newVal).length > 0) {
          this.initColumns(newVal)
        }
      },
      deep: true,
      immediate: true
    },
    dataSourceName: {
      handler(nVal, oVal) {
        if (nVal && nVal !== oVal && (!this.controlConfig || Object.keys(this.controlConfig).length === 0)) {
          this.initControls().then(config => {
            this.initColumns(config)
          })
        }
      },
      deep: true,
      immediate: true
    },

    formData: {
      deep: true,
      immediate: true,
      handler(newVal, oldVal) {
        if (newVal && this.controlInfos) {
          let data = []
          if (!this.hasObject(newVal, 'data') && getVarType(newVal) === 'array' && newVal.length > 0) {
            newVal.map(i => {
              data.push({
                id: i.keyInfoView.id,
                keyInfo: i.keyInfo,
                keyInfoView: i.keyInfoView,
                keyInfoObject: i.keyInfoObject
              })
            })
          }
          if (this.hasObject(newVal, 'data') && getVarType(newVal.data) === 'array') {
            newVal.data.map(i => {
              data.push({
                id: i.keyInfo.id,
                keyInfo: i.keyInfo,
                keyInfoView: i.keyInfo,
                keyInfoObject: i.keyInfo
              })
            })
          }
          this.tableData = setFormData(data, this.controlInfos, this)
        }
      }
    }
  },
  methods: {
    // 初始化
    initColumns(config) {
      const {controlInfos, controlProps, dataSource} = config
      // 解除js对象指向同一内存地址 JSON.parse(JSON.stringify(Object | Array))
      this.controlInfos = JSON.parse(JSON.stringify(controlInfos))
      this.controlProps = JSON.parse(JSON.stringify(controlProps))
      this.dataSource = JSON.parse(JSON.stringify(dataSource))
      this.edFormConfig = JSON.parse(JSON.stringify(config))
      this.columns = this.columns.length === 0 ? this.getColumns(controlInfos, controlProps) : this.columns
      this.getSlotNames(this.columns)
    },

    // 插槽项
    getSlotNames(columns) {
      columns.map(column => {
        this.slotNames.push(getPath(column.prop) + 'Column')
      })
    },

    // 编辑
    handlerEdit(row, index) {
      this.visible = true
      this.drawerTit = '编辑'
      this.cacheIndex = index
      this.edFormData = row
    },

    // 删除
    handlerDelete(row, index) {
      this.tableData.splice(index, 1)
    },

    // 新增
    handlerAdd() {
      this.visible = true
      this.drawerTit = '新增'
      this.cacheIndex = null
      this.edFormData = {}
      setTimeout(() => {
        this.$refs.easyDataForm.resetFields()
      }, 100)
    },

    // 确认弹窗
    async handlerOk() {
      const data = await this.$refs.easyDataForm.getFormData(true, true)
      if (data) {
        data.keyInfoView = Object.assign(data.key, this.bizParams)
        if (this.cacheIndex != null) {
          this.tableData.splice(this.cacheIndex, 1, data)
        } else {
          this.tableData.push(data)
        }
        this.tableData = setFormData(this.tableData, this.controlInfos, this)
        this.handlerClose()
      }
    },

    // 关闭弹窗
    handlerClose() {
      this.visible = false
    },
    /**
     * 获取表单数据
     * @param isValidate
     * @returns {Promise<unknown>}
     */
    getFormData() {
      return new Promise((resolve) => {
        resolve(Object.assign({}, {
          dataSourceName: this.dataSourceName,
          data: setTableData(this.tableData)
        }))
      })
    },
    /**
     * @name getType
     * @returns {string}
     * @description 设置当前模版类型
     */
    getType() {
      return this.moduleProp?.showAddBtn || this.moduleProp?.showAction ? TempType.save : TempType.view
    },
  }
}
</script>

<style scoped>
.btn {
  margin-bottom: 10px;
}
</style>
