<template>
  <a-form
    v-if="typeof value.list !== 'undefined' && typeof value.config !== 'undefined'"
    class="k-form-build-9136076486841527"
    :layout="value.config.layout"
    :hideRequiredMark="value.config.hideRequiredMark"
    :form="form"
    :linkageMap="linkageMap"
    @setLinkageMap="setLinkageMap"
    @submit="handleSubmit"
    :style="value.config.customStyle"
    :selfUpdate="value.config.selfUpdate || false"
  >
    <div style="padding-bottom: 20px;position:relative;">
      <div class="content-buildBlocks">
        <buildBlocks
          @handleReset="handleReset"
          @doButtonAction="doButtonAction"
          v-for="(record, index) in value.list"
          :record="record"
          :isdetail="!buttonDatas"
          v-bind="$attrs"
          :config="value.config"
          :key="index"
          @addEditableTableVm="addEditableTableVm"
          @addModelKey="addModelKey"
          @setFieldValue="setFieldValue"
          @getFieldValue="getFieldValue"
          :allDataSource="allDataSource"
          @refreshAllData="$emit('refreshAllData')"
          :form-id="formId"
          :dictMap="dictMap"
          :elValue="elValue"
          :dsCode="dsCode"
          :form="form"
          :linkageMap="linkageMap"
          @setLinkageMap="setLinkageMap"
          @setHidden="setHidden"
          @setTabHidden="setTabHidden"
          :fks="fks"
          :stores="stores"
          :uploadTimestamp="uploadTimestamp"
        />
      </div>
    </div>
    <form-redirect-modal ref="form" :stores="stores"
                         @closeTopPage="closeTopPage"></form-redirect-modal>
  </a-form>
</template>
<script>

import buildBlocks from "./buildBlocks";
import {getRefPromise, validateFormAndTables, getFormAndTableValues} from '../utils/YchVxeTableUtil';
import {handleCreateFunc, handleExecFunc} from '../utils/actions'
import LocleUtil from "../utils/LocleUtil";
import common from "../utils/common";
import formRedirectModal from "../components/redirect/FormRedirectModal.vue";
export default {
  name: "KFormBuild",
  data() {
    return {
      form: this.$form.createForm(this),
      linkageMap: {},
      editableTableRefs: {},
      timer: null,
      mainFormLoaded: false,//判断是否手工触发，初始化加载时值为false，手工触发为true
      componentFile: null,
      componentUrl: null,
      componentObj: {},
    };
  },
  props: {
    value: Object,
    allDataSource: {
      type: Object,
      default: () => {
      }
    },
    dictMap: {
      type: Object,
      default: () => {
      }
    },
    elValue: {
      type: Object,
      default: () => {
      }
    },
    dsCode: {
      type: Object,
      default: () => {
      }
    },
    formId: {
      type: String
    },
    fks: {
      type: Array,
      default: () => []
    },
    stores: {
      type: Object,
      default: () => {
        return {}
      }
    },
    uploadTimestamp: {
      type: String
    },
    // 流程iD
    processDefId: {
      type: String
    },
    buttonDatas: {
      type: Object,
      default: () => {
      }
    },
    //点击流程时代入id
    stepId: {
      type: String,
      default: null
    }
  },
  components: {
    buildBlocks,
    formRedirectModal
  },
  methods: {
    //关闭顶层
    closeTopPage() {
      this.$emit('close', true)
    },
    getItemObj(key) {
      let jsonList = this.value.list
      return common.findItemByKey(jsonList, key);
    },
    setTabHidden(key, isHidden) {
      let jsonList = this.value.list
      this.hiddenTab(jsonList, key, isHidden)
    },
    hiddenTab(jsonList, key, isHidden) {
      if (!jsonList) {
        return
      }
      jsonList.forEach(vo => {
        if (vo.type === 'tabs') {
          vo.tabs.forEach(tab => {
            if (tab.key === key) {
              tab.hidden = isHidden
            }
          })
        } else {
          this.hiddenTab(vo.list, key, isHidden)
          this.hiddenTab(vo.trs, key, isHidden)
          this.hiddenTab(vo.tds, key, isHidden)
          this.hiddenTab(vo.columns, key, isHidden)
          this.hiddenTab(vo.tabs, key, isHidden)
        }
      })
    },
    setHidden(tableName, modelName, isHidden) {
      let jsonList = this.value.list
      this.hiddenModel(jsonList, tableName, modelName, isHidden)
    },
    hiddenModel(jsonList, tableName, modelName, isHidden) {
      if (!jsonList) {
        return
      }
      jsonList.forEach(vo => {
        if (vo.dataId && vo.dataId === modelName) {
          vo.options.hidden = isHidden
        } else if (vo.model && vo.tableName === tableName && vo.model === modelName) {
          vo.options.hidden = isHidden
        } else if (vo.type === 'editableTable' && vo.tableName && vo.tableName === tableName) {
          vo.options.hidden = isHidden
        } else if (vo.tab && vo.tab === modelName) {
          vo.hidden = isHidden
        } else {
          this.hiddenModel(vo.list, tableName, modelName, isHidden)
          this.hiddenModel(vo.trs, tableName, modelName, isHidden)
          this.hiddenModel(vo.tds, tableName, modelName, isHidden)
          this.hiddenModel(vo.columns, tableName, modelName, isHidden)
          this.hiddenModel(vo.tabs, tableName, modelName, isHidden)
        }
      })
    },
    setLinkageMap(key, value, keep) {
      if (!keep) {
        this.mainFormLoaded = true;
        this.linkageMap = {...this.linkageMap}
        this.linkageMap[key] = value;
      } else {
        this.linkageMap[key] = value;
        // 200毫秒后触发联动，200毫秒内不重复触发，主要是考虑加载时的性能问题
        clearTimeout(this.timer)
        this.timer = setTimeout(this.reloadLinkageMap, 200);
      }
    },
    reloadLinkageMap() {
      this.linkageMap = {...this.linkageMap}
    },
    //记录子表控件
    addEditableTableVm(key, vm) {
      this.editableTableRefs[key] = vm;
    },
    addModelKey(key) {
      this.$emit("addModelKey", key);
    },
    setFieldValue(key, value) {
      //TODO 暂时不处理不画控件的情况
      const item = {};
      item[key] = value;
      this.form.setFieldsValue(item)
    },
    getFieldValue(key, func) {
      let value = this.form.getFieldValue(key)
      if (!value && this.fks) {
        for (let i = 0; i < this.fks.length; i++) {
          const item = this.fks[i];
          const humpKey = this.toHump(item.colCode);
          if (humpKey == key) {
            value = item.queryValue
            break;
          }
        }
      }
      func(value)
    },
    toHump(name) {
      return name.replace(/\_(\w)/g, function (all, letter) {
        return letter.toUpperCase()
      })
    },
    getAllTable() {
      let values = Object.keys(this.editableTableRefs).map(key => getRefPromise(this.editableTableRefs[key], key));
      return Promise.all(values);
    },
    classifyIntoFormData(allValues) {
      let main = Object.assign({}, allValues.formValue)
      Object.keys(this.editableTableRefs).forEach((key, index) => {
        main[key + 'List'] = allValues.tablesValue[index].values;
      });
      return main;
    },
    // moment,
    handleSubmit(e) {
      // 提交按钮触发，并触发submit函数，返回getData函数
      e.preventDefault();
      this.$emit("submit", this.getData());
    },
    handleReset() {
      // 重置表单
      this.form.resetFields();
    },
    doButtonAction(action) {
      if (!action) {
        this.$message.warning(LocleUtil.getLocale('m.eform.formDesign.label.wei-pei-zhi-shi-jian-dai-ma'))
        return
      }
      function replaceAll(str, find, replace) {
        return str.replace(new RegExp(find, 'g'), replace);
      }
      let result = replaceAll(action,"messageUtil", "$message");
      const func = handleCreateFunc(result, this)
      handleExecFunc(func, {})
    },
    close() {
      this.$emit("close")
    },
    getData() {
      // 提交函数，提供父级组件调用
      return new Promise((resolve, reject) => {
        try {
          /** 触发表单验证 */
          this.getAllTable().then(tables => {
            /** 一次性验证主表和所有的次表 */
            return validateFormAndTables(this.form, tables)
          }).then(allValues => {
            resolve(this.classifyIntoFormData(allValues));
          }).catch(e => {
            reject(e.error);
          });
        } catch (err) {
          reject(err);
        }
      });
    }
  },
  mounted() {
    // 加载完成后，只进行一次联动数据的变化
    this.$nextTick(() => {
      this.linkageMap = {...this.linkageMap}
    })
  }
};
</script>

<style lang="less" scoped>
.stepStyle {
  cursor: pointer;
  position: relative;
  overflow: hidden;
  //top: 20px;
  width: 145px;
  background: #F8F8F9;
  border-radius: 0px 0px 0px 0px;
  opacity: 1;
  border: 1px solid #E1E3E5;

  .item-step {
    position: relative;
    top: 20px;
    left: 13px;
  }

  /deep/ .ant-steps-icon {
    color: #13C2C2 !important;
  }

  .chooseStyle {
    //background: linear-gradient(-145deg, transparent 18px, #f4f4f4 0);
    //background-color: transparent !important;

    /deep/ .ant-steps-item-title {
      color: #1A64F4 !important;
      //font-weight: 700;
    }

    /deep/ .ant-steps-item-icon {
      border: none !important;
      color: #fff !important;
      background: #1A64F4 !important;
    }

    /deep/ .ant-steps-icon {
      color: #fff !important;
    }
  }

  .unChooseStyle {
    /deep/ .ant-steps-item-title {
      color: #000;
      //font-weight: 700;
    }

    /deep/ .ant-steps-item-icon {
      background: #E0F6EF !important;
      border: none !important;
      color: #13C2C2 !important;
    }
  }

  .ant-steps-item-disabled {
    /deep/ .ant-steps-item-icon {
      background: #fff !important;
      border: 1px solid #333333 !important;
      color: #333 !important;
    }

    /deep/ .ant-steps-icon {
      color: #333 !important;
    }
  }
}

.stepStyle /deep/ .ant-steps-item {
  //background-color: #f4f4f4;
  //margin-top: 0.5vh;
  //font-weight: 700;
  //height: 65px;
}

.stepStyle /deep/ .ant-steps-item-title {
  font-size: 12px;
  //position: relative;
  //top: 50%;
  //transform: translate(0, 50%);
}

.arrow {
  position: absolute;
  top: 30%;
  z-index: 999;
  width: 10px;
  height: 40px;
  background: #E1E3E5;
  border-radius: 0px 2px 2px 0px;
  opacity: 1;
  cursor: pointer;
}

.activeIcon {
  color: #2F54EB;
}

//布局相关
.hasProcessObj {
  width: calc(100% - 145px);
  padding-left: 1%;
}

.isProcessRight {
  padding-right: 1%;
}

.isProcessTop {
  padding-bottom: 2%;
  width: 100%;
  height: 100%;
  justify-content: center;
  margin-bottom: 2%;
  //margin-left: 1vw;

  /deep/ .ant-steps {
    display: flex;
    justify-content: center;
  }

  /deep/ .ant-steps-item {
    flex: 1;
    margin-right: 1vw;
  }
}

.isRight {
  flex-direction: row-reverse;
}

.isTop {
  flex-direction: column;
}

.ant-row /deep/ .ant-form-item {
  display: flex;
  align-items: center;
  position: relative;
}
</style>
