<template>
  <div>
    <a-spin :spinning="spinning !== 0">
      <div class="table-operator">
        <a-button v-if="config.buttonNew" type="primary" icon="plus" @click="handleAdd">
          {{addButName}}
        </a-button>
        <a-button v-if="config.buttonEdit" type="default" icon="edit" @click="handleEdit">
          {{editButName}}
        </a-button>
        <a-button v-if="config.buttonDel" type="default" icon="delete" @click="handleDel">{{ $locale('m.common.button.delete') }}</a-button>
      </div>
      <a-tree
        :expandedKeys.sync="expandedKeys"
        :showLine="true"
        :tree-data="treeData"
        @select="onSelect"
        :load-data="onLoadData"
        :selectedKeys="selectedKeys"
        :loadedKeys="loadedKeys"
      />
    </a-spin>
    <form-redirect-modal ref="form" @refreshParent="modalFormOk" :stores="stores"></form-redirect-modal>
  </div>
</template>

<script>

  import { getAction, postAction, deleteAction } from '../../utils/manage'
  import FormRedirectModal from './FormRedirectModal'
  import YchConstant from '../../utils/YchConstant'
  import RelationUtil from "./RelationUtil";
  import RefreshUtil from './RefreshUtil'
  import LocleUtil from "../../utils/LocleUtil";
  import locleUtil from "../../utils/LocleUtil";

  export default {
    name: 'TreeRedirect',
    components: {
      FormRedirectModal
    },
    props: {
      viewCode: String,
      subViews: Object,
      relationStatus: String,
      relationOpenFks: String,
      relationList: Array,
      refreshMap: Object,
      isShowInTab: Boolean,
      stores: {
        type: Object,
        default: () => {
          return {}
        }
      },
      tabConfig: Object
    },
    data() {
      return {
        spinning: 0,
        treeData: [],
        loadedKeys: [],
        selectedKeys: [],
        selectedNode: null,
        expandedKeys: [],
        url: {
          getViewModel: YchConstant.PREFIX_EFORM + '/engine/viewEngine/getViewModel',
          queryTreeList: YchConstant.PREFIX_EFORM + '/engine/viewEngine/queryTreeList',
          delTreeData: YchConstant.PREFIX_EFORM + '/engine/viewEngine/delTreeData'
        },
        config: {},
        tableName: null,
        tableNameArr: [],
        refreshType: null,
        fks: [],
        refreshObj: {},
        loaded: false,
        syncNum: 0, // 防止异步
      }
    },
    computed: {
      addButName() {
        if(this.config.addAlias){
          return this.config.addAlias
        }else{
          if (!this.config.parentKeyName) {
            return this.$locale('m.common.button.add')
          } else {
            return this.selectedKeys.length === 0 ? this.$locale('m.eform.formDesign.label.xin-zeng-gen-jie-dian') : this.$locale('m.eform.formDesign.label.xin-zeng-zi-jie-dian')
          }
        }
      },
      editButName() {
        if(this.config.editAlias){
          return this.config.editAlias
        }else{
          return this.$locale('m.common.button.update')
        }
      },
    },
    created() {
      if (this.subViews && this.subViews[this.viewCode]) {
        this.init(this.subViews[this.viewCode])
      } else {
        this.spinning++
        getAction(this.url.getViewModel, { viewCode: this.viewCode }).then((res) => {
          if (res.success) {
            this.init(res.result)
          } else {
            this.$message.warning(res.message)
          }
        }).finally(() => {
          this.spinning--
        })
      }

      // 把当前对象放入stores，方便其他对象使用
      if (!this.stores.$vm) {
        this.stores.$vm = {}
      }
      this.stores.$vm[this.viewCode] = this
    },
    watch: {
      refreshMap: {
        handler() {
          if (this.selectedKeys.length === 0) {
            return
          }
          let isOk = false
          this.tableNameArr.forEach(tableName => {
            if (isOk) {
              return
            }
            isOk = this.watchRefreshMap(tableName);
          })
        }
      },
      relationList: {
        handler() {
          const _fks = this.fks
          this.initRelation()
          if (_fks !== this.fks) {
            this.onLoadData()
          }
        }
      },
    },
    inject: {
      addRouter: {
        from: 'addRouter',
        default: () => {
          return () => {
          }
        }
      },
    },
    methods: {
      watchRefreshMap(tableName) {
        const _val = this.refreshObj[tableName]
        this.refreshObj[tableName] = RefreshUtil.getRefreshValue(this.refreshMap, {
          tableName: tableName,
          refreshObj: this.refreshObj[tableName],
        })
        if (_val !== this.refreshObj[tableName]) {
          // 1是刷新子节点，2是刷新本级节点
          this.refreshType = this.refreshObj[tableName].type === 'form' ? '2' : '1'
          this.modalFormOk()
          return true
        }
      },
      initRelation() {
        this.fks = RelationUtil.getChangedRelation({
          relationList: this.relationList,
          tableName: this.tableName,
          fks: this.fks,
          relationOpenFks: this.relationOpenFks,
        })
      },
      init(result) {
        const treeData = result.treeData ? JSON.parse(result.treeData) : {}
        if (treeData.type === '1') {
          //普通模式
          this.config = treeData.data || {}
          this.tableName = this.config.tableName

          if (this.tableNameArr.indexOf(this.tableName) === -1) {
            this.tableNameArr.push(this.tableName)
          }
        } else {
          this.config = {}
          if(treeData.data.length > 0){
            this.tableName = treeData.data[0].tableName
            this.reSetObjRelation(treeData.data[0])
          }
        }

        this.initRelation()
        if (!this.loaded && this.checkFks()) {
          this.onLoadData(null, true)
        }
      },
      reSetObjRelation(data){
        const tableName = data.tableName
        if(data.children && data.children.length > 0){
          for(let i = 0; i < data.children.length; i++){
            this.reSetObjRelation(data.children[i])
          }
        }
        if (this.tableNameArr.indexOf(tableName) === -1) {
          this.tableNameArr.push(tableName)
        }
      },
      onLoadData(treeNode, isInit) {
        this.loaded = true
        return new Promise(resolve => {
          if (treeNode && treeNode.dataRef.children) {
            this.loadedKeys.push(treeNode.dataRef.key)
            resolve()
            return
          }
          this.spinning++
          const parameter = {
            fks: this.fks || []
          }
          if (treeNode) {
            parameter.treeShowId = treeNode.dataRef.attributes.treeShowId
            parameter.treeParameter = treeNode.dataRef.attributes.treeParameter
          }
          this.syncNum ++
          const syncNum = this.syncNum
          postAction(this.url.queryTreeList + '?viewCode=' + this.viewCode, parameter).then((res) => {
            // 防止异步
            if(syncNum !== this.syncNum){
              return;
            }
            if (res.success) {
              if (treeNode) {
                this.filterChildren(res.result)
                treeNode.dataRef.children = res.result
                this.treeData = [...this.treeData]
                this.loadedKeys.push(treeNode.dataRef.key)
              } else {
                this.treeData = res.result
                this.loadedKeys = []

                if (this.selectedKeys.length > 0 && !this.treeData.find(vo => vo.key === this.selectedKeys[0])) {
                  this.setPkNull()
                  this.selectedKeys = []
                  this.selectedNode = null
                }

                this.expandedKeys = []
                this.setExpandedKeys(this.treeData || [])
              }

              if (isInit) {
                //初始化时
                this.clickRoot()
              }
              resolve()
            } else {
              this.$message.warning(res.message)
            }
          }).finally(() => {
            this.spinning--
          })
        })
      },
      setExpandedKeys(treeData) {
        const that = this
        treeData.forEach(vo => {
          if (vo.children) {
            that.expandedKeys.push(vo.key)
            that.setExpandedKeys(vo.children)
          }
        })
      },
      filterChildren(result) {
        const subIdArr = result.map(vo => vo.key)
        const expandedKeys = this.expandedKeys.filter(key => subIdArr.indexOf(key) === -1)
        this.expandedKeys = expandedKeys
        const loadedKeys = this.loadedKeys.filter(key => subIdArr.indexOf(key) === -1)
        this.loadedKeys = loadedKeys
      },
      onSelect(selectedKeys, info) {
        if (selectedKeys.length === 0 && !this.config.buttonNew) {

        } else if(selectedKeys.length === 0){
          this.setPkNull()
          this.selectedKeys = []
          this.selectedNode = null
        } else {
          this.selectedKeys = selectedKeys
          this.selectedNode = info.node
          const tableName = info.node.dataRef.attributes.tableName
          const treeParameter = info.node.dataRef.attributes.treeParameter
          if (tableName && treeParameter) {
            this.refreshPk(JSON.parse(treeParameter), tableName)
          }
        }
      },
      isParentTable(tableName) {
        return RelationUtil.isParentTable({
          relationList: this.relationList,
          tableName: tableName,
          relationStatus: this.relationStatus,
        })
      },
      refreshPk(args, tableName) {
        const that = this;
        this.tableNameArr.forEach(item => {
          if (!that.isParentTable(item)) {
            return
          }
          if (item !== tableName) {
            that.$emit('setPk', {
              record: {},
              tableName: item,
              relationStatus: that.relationStatus,
            })
          }
        })
        if (!that.isParentTable(tableName)) {
          return
        }
        that.$emit('setPk', {
          record: args,
          tableName: tableName,
          relationStatus: that.relationStatus,
        })
      },
      setPkNull() {
        if (!this.selectedNode) {
          return
        }
        const tableName = this.selectedNode.dataRef.attributes.tableName
        this.refreshPk({}, tableName)
      },
      //点击根节点
      clickRoot() {
        if (this.selectedKeys.length > 0) {
          //已经点击过
          return
        }
        if (this.treeData && this.treeData.length > 0) {
          const rootData = this.treeData[0]
          this.selectedKeys = [rootData.key]
          const tableName = rootData.attributes.tableName
          const treeParameter = rootData.attributes.treeParameter
          this.selectedNode = {
            dataRef: rootData
          }
          if (tableName && treeParameter) {
            this.refreshPk(JSON.parse(treeParameter), tableName)
          }
        }
      },
      checkFks () {
        return RelationUtil.checkFks({
          fks: this.fks,
        })
      },
      handleAdd() {
        const formCode = this.config.formNew
        if (!formCode) {
          this.$message.warning(this.$locale('m.eform.formDesign.label.mei-you-pei-zhi-guan-lian-biao-dan'))
          return
        }
        if (!this.checkFks()) {
          this.$message.warning(this.$locale('m.eform.formDesign.label.checkFks_error'))
          return
        }
        const fks = []
        const fpk = this.fks.find(item =>item.colCode === this.config.parentKeyName)
        if (this.config.parentKeyName) {
          if (this.selectedKeys.length === 0){
            if(fpk) {
              fks.push({
                colCode: this.config.parentKeyName,
                queryValue: fpk.queryValue
              })
            } else if (this.config.rootValue) {
              fks.push({
                colCode: this.config.parentKeyName,
                queryValue: this.config.rootValue
              })
            }
          } else {
            fks.push({
              colCode: this.config.parentKeyName,
              queryValue: this.selectedKeys[0]
            })
          }
        }

        if (this.fks.length > 0 && fpk) {
          const temp = fks.find(vo => vo.colCode === fpk.colCode);
          if (!temp) {
            fks.push({
              colCode: fpk.colCode,
              queryValue: fpk.queryValue
            })
          }
        }
        this.refreshType = '1'

        let router = null
        if (this.config.dialogSize === 'tab') {
          if (!this.isShowInTab) {
            this.config.dialogSize = null
            // this.$message.warning("弹框模式下不支持使用新页签打开方式")
          } else {
            router = this.addRouter({
              path: '/eform/add/' + formCode,
              component: resolve => require(['../redirect/FormRedirectTab.vue'], resolve),
              props: {
                formCode: formCode,
                func: 'add',
                fks: fks,
              },
              meta: {
                title: this.$locale('m.eform.formDesign.label.xin-zeng-biao-dan'),
              }
            }, true);
          }
          if (router) {
            this.$router.push(router)
          }
        }
        if (!router) {
          this.$refs.form.add(formCode, fks, "", this.config.dialogSize)
        }
      },
      handleEdit() {
        const formCode = this.config.formEdit
        if (!formCode) {
          this.$message.warning(this.$locale('m.eform.formDesign.label.mei-you-pei-zhi-guan-lian-biao-dan'))
          return
        }
        if (this.selectedKeys.length === 0) {
          this.$message.warning(this.$locale('m.common.tip.select_one_warn'))
          return
        }
        this.refreshType = '2'

        let router = null
        if (this.config.dialogSize === 'tab') {
          if (!this.isShowInTab) {
            this.config.dialogSize = null
            // this.$message.warning("弹框模式下不支持使用新页签打开方式")
          } else {
            router = this.addRouter({
              path: '/eform/edit/' + formCode + "/" + this.selectedKeys[0],
              component: resolve => require(['../redirect/FormRedirectTab.vue'], resolve),
              props: {
                formCode: formCode,
                func: 'edit',
                formId: this.selectedKeys[0],
              },
              meta: {
                title: this.$locale('m.eform.formDesign.label.bian-ji-biao-dan'),
              }
            });
          }
          if (router) {
            this.$router.push(router)
          }
        }
        if (!router) {
          this.$refs.form.edit(this.selectedKeys[0], formCode, this.config.dialogSize)
        }
      },
      $locale(params){
        return locleUtil.getLocale(params)
      },
      handleDel() {
        if (this.selectedKeys.length === 0) {
          this.$message.warning(this.$locale('m.common.tip.select_one_warn'))
          return
        }
        //TODO 多选
        let ids = this.selectedKeys[0]
        const that = this
        this.$confirm({
          title: this.$locale('m.common.title.delete'),
          content: this.$locale('m.common.tip.delete_confirm'),
          okText: LocleUtil.getLocale('m.common.button.ok'),
          cancelText: LocleUtil.getLocale('m.common.button.cancel'),
          onOk: function() {
            that.spinning++
            deleteAction(that.url.delTreeData, {
              ids: ids,
              viewCode: that.viewCode
            }).then((res) => {
              if (res.success) {
                that.$message.success(res.message)
                that.refreshType = '2'
                that.modalFormOk()
              } else {
                that.$message.warning(res.message)
              }
            }).finally(() => {
              that.spinning--
            })
          }
        })
      },
      modalFormOk() {
        if (this.selectedKeys.length === 0 || !this.config.parentKeyName) {
          this.onLoadData()
          return
        }
        if (this.refreshType === '1') {
          this.selectedNode.dataRef.children = null
          this.loadedKeys = this.loadedKeys.filter(key => key !== this.selectedNode.dataRef.key)
        } else if (this.refreshType === '2' && this.selectedNode.$parent && this.selectedNode.$parent.dataRef) {
          this.selectedNode.$parent.dataRef.children = null
          this.loadedKeys = this.loadedKeys.filter(key => key !== this.selectedNode.$parent.dataRef.key)
          this.setPkNull()
          this.selectedKeys = []
          this.selectedNode = null
        } else {
          this.onLoadData()
        }
      }
    }
  }
</script>
