<template>
  <div v-loading="loading">
    <div v-if="!loading">
      <lab-form :element="element" :elements="elements" :index="index" :model-data="modelData" />
    </div>

    <el-dialog :visible.sync="formVisible" center :title="formView.label" :width="formWidth" append-to-body destroy-on-close :close-on-click-modal="false" :close-on-press-escape="false">
      <lab-view v-if="formVisible" :element="formView" :model-data="activeRow" />
    </el-dialog>
  </div>
</template>

<script>
import LabBase from "../../mixins/LabBase";
import LabRequest from "../../mixins/LabRequest";

export default {
  name: "LabFormTable",
  mixins: [LabBase,LabRequest],
  provide(){
    return {
      formTable: this
    }
  },
  data() {
    return {
      loading: true,
      formVisible: false,
      formWidth: '80%',
      formView: {},
      activeRow: {}
    }
  },
  watch: {
    'element.props.showType'(newVal){
      if (this.labDesign.switch && newVal) {
        this.initView()
      }
    }
  },
  created() {
    this.loading = true
    this.$LabRender.autoFill(this.element, this)
    this.initView()
  },
  methods: {
    initView() {
      const { render, elements, props } = this.element
      if (elements.length === 0) {
        // 顶部默认按钮
        const topGroup = this.$LabRender.create('buttonGroup', '表格上方',render);
        topGroup.elements.push(this.createBtn('新增','$tableAdd',
            "const { $this } = args;\n const { formTable } = $this;\n formTable.openForm();\n resolve(200);\n",
            { type: 'primary', icon: 'iconfont icon-form-add' }))
        elements.push(topGroup)

        // 行内默认按钮内
        const rowGroup = this.$LabRender.create('buttonGroup', '操作',render);
        rowGroup.elements.push(this.createBtn('编辑','$rowEdit',
            "const { $this } = args;\n const { formTable } = $this;\n formTable.rowEdit(args);\n resolve(200);\n",
            { type: 'success', icon: 'iconfont icon-edit-one' }))
        rowGroup.elements.push(this.createBtn('删除','$rowDel',
            "const { $this } = args;\n const { formTable } = $this;\n formTable.rowDelete(args).then(res => resolve(200));",
            { type: 'danger', icon: 'iconfont icon-remove-one' }))
        rowGroup.lifeScope = 'table'

        // 表单按钮
        const formGroup = this.$LabRender.create('buttonGroup', '表单底部',render);
        formGroup.elements.push(this.createBtn('保存','$formSave',
            "const { $this } = args;\n const { formTable } = $this;\n formTable.formSave(args).then(res => resolve(200));",
            { type: 'primary', icon: 'iconfont icon-submit-success' }))
        formGroup.elements.push(this.createBtn('关闭','$formCancel',
            "const { $this } = args;\n const { formTable } = $this;\n formTable.closeForm();\n resolve(200);\n",
            { type: 'default', icon: 'iconfont icon-back-one' }))
        formGroup.lifeScope = 'form'
        formGroup.props = { align: 'center' }

        // 表格
        const table = this.$LabRender.create('table', '表格',render);
        table.elements.push(rowGroup)
        table.elements.push(formGroup)
        props.tableMapper = table.mapper
        elements.push(table)
      }
      const table = elements.find(item => item.mapper === props.tableMapper)
      if (table) {
        this.$set(table, 'render', props.showType === 'form' ? props.showType : 'table')
        if (props.showType === 'formTable') {
          this.$set(table, 'selfType', 'edit')
        } else {
          this.$delete(table, 'selfType')
        }
      } else {
        this.$resultMsg(this, { code: 500, msg: '未找到表格组件'})
      }
      this.loading = false
    },
    createBtn(label, mapper, callFun, props) {
      const btn = this.$LabRender.create('button',label)
      btn.events = [{ trigger: 'click', eventScript: callFun }]
      this.$Util.copyAttr(props, btn.props)
      btn.mapper = mapper
      return btn
    },
    formSave(args) {
      return new Promise(resolve => {
        const { modelData } = args
        const { requests } = this.element
        const request = requests.find(item => item.trigger === 'save')
        const $table = this.findTable()
        if (!$table) {
          return
        }
        if (request) {
          this.dispatchRequest('save', modelData, modelData)
              .then(res => {
                this.$resultMsg(this, res)
                if (res.code === 200){
                  $table.loadSource()
                  this.closeForm()
                }
                resolve(res)
              })
        } else {
          $table.addData(args.modelData)
          this.$resultMsg(this, { code: 200, msg: '添加成功'})
          this.closeForm()
          resolve({code:200})
        }
      })
    },
    openForm() {
      const { elements } = this.element
      const table = elements.find(item => item.render === 'table')
      if (table) {
        this.formView = this.$Util.copy(table)
        this.formView.render = 'form'
      } else {
        this.$resultMsg(this, { code: 500, msg: '表单生成失败'})
        return
      }
      this.formVisible = true
    },
    closeForm(){
      this.activeRow = {}
      this.formVisible = false
    },
    findTable(){
      const { elements, props } = this.element
      const table = elements.find(item => item.mapper === props.tableMapper)
      if (table) {
        const $tables = this.findElement(table.mapper)
        if ($tables) {
          return $tables
        }
      }
      this.$resultMsg(this, { code: 500, msg: '未找到表格组件'})
      return null;
    },
    rowEdit(args) {
      this.activeRow = this.$Util.copy(args.modelData)
      this.openForm()
    },
    rowDelete(args){
      return new Promise(resolve => {
        const { requests } = this.element
        const request = requests.find(item => item.trigger === 'remove')
        const $table = this.findTable()
        if (!$table) {
          return
        }
        if (request) {
          const { modelData } = args
          this.confirmExecute({},request, modelData, modelData)
              .then(res => {
                this.$resultMsg(this, res)
                if (res.code === 200){
                  $table.loadSource()
                  this.closeForm()
                }
                resolve(res)
              })
        } else {
          $table.removeData(args.modelData)
          this.$resultMsg(this, { code: 200, msg: '删除成功'})
          resolve({ code: 200 })
        }
      })
    }
  }
}
</script>

<style scoped>

</style>
