<template>
  <a-form v-bind="formModelProps" :model="props.formData" ref="formRef" style="width: 100%">
    <a-row :style="{ height: '100%' }" :gutter="formConfig?.config?.rowGutter">
      <template v-for="item in formConfig.formItems" :key="item.itemId">
        <FormViewerLayout
          :record="item"
          :formConfig="formConfig"
          :readonly="props.readonly"
          :formRef="formRef"
          v-model:formData="props.formData"
        />
      </template>
    </a-row>
  </a-form>
</template>

<script setup name="FormViewer">
import { ref, onMounted, computed, provide, watch } from 'vue';
import { omit } from 'lodash-es';
import FormViewerLayout from './form-viewer-layout.vue';
import { message } from 'ant-design-vue/es';
import Request from '@/utils/request/request-util';
import { deepClone } from '@/utils/common/util';

const props = defineProps({
  formData: {
    type: Object,
    default: {}
  },
  record: Object,
  // 配置
  config: {
    type: Object,
    default: null
  },
  // 是否是编辑
  isEdit: {
    type: Boolean,
    default: false
  },
  // 是否只读
  readonly: {
    type: Boolean,
    default: false
  }
});

// ref
const formRef = ref();

// 表单配置
const formConfig = ref({
  activeKey: 1,
  formItems: [],
  currentItem: {
    componentCode: '',
    props: {}
  }
});

// 表单每一项的配置
let formObj = {
  formData: {}
};

onMounted(() => {
  if (props.record) {
    formConfig.value.formItems = props.record.formItemList;
    formConfig.value.config = props.record.formConfig;
  } else if (props.config) {
    formConfig.value = deepClone(props.config);
  }

  // 设置
  formObj.formData = props.formData;
  ergodicItem(formConfig.value.formItems, formObj);
  initBefore();
});

// 加载之前
const initBefore = () => {
  if (formConfig.value?.config?.initBefore) {
    const func = new Function('formObj', 'Request', formConfig.value.config.initBefore);
    func(formObj, Request);
  }
};
// 加载之后
const initAfter = () => {
  if (formConfig.value?.config?.initAfter) {
    const func = new Function('formObj', 'Request', formConfig.value.config.initAfter);
    func(formObj, Request);
  }
};

// 遍历每一项
const ergodicItem = (arr, formObj) => {
  let otherCode = ['grid', 'collapse', 'col'];
  if (arr?.length > 0) {
    arr.forEach(async item => {
      if (otherCode.includes(item.componentCode)) {
        formObj[item.componentCode + '_' + item.itemId] = item;
      } else {
        formObj[item.fieldCode] = item;
      }
      if (item?.children?.length > 0) {
        let itemKey = otherCode.includes(item.componentCode) ? item.componentCode + '_' + item.itemId : item.fieldCode;
        ergodicItem(item.children, formObj[itemKey]);
      }
    });
  }
};

/**
 * 获取表单属性
 */
const formModelProps = computed(() => omit(formConfig.value.config, ['disabled', 'labelWidth']));

// 校验是否必填
const validate = () => {
  return new Promise(resolve => {
    Promise.all([formRef.value.validate()])
      .then(result => {
        if (result.indexOf(false) >= 0) {
          resolve(false);
        } else {
          resolve(true);
        }
      })
      .catch(e => {
        message.warning(e.errorFields[0].errors[0]);
        resolve(false);
      });
  });
};

watch(
  () => props.isEdit,
  val => {
    if (val) {
      formObj.formData = props.formData;
      getTableEachColumn(formConfig.value.formItems);
      initAfter();
    }
  },
  { deep: true, immediate: true }
);

// 获取编辑时，表格的每一项配置
const getTableEachColumn = arr => {
  if (arr?.length > 0) {
    arr.forEach(item => {
      if (item.componentCode == 'table') {
        let columnList = [];
        let columnConfig = {};
        if (item?.children) {
          item.children.forEach(a => {
            if (!a.itemHiddenFlag) {
              columnConfig[a.fieldCode] = a;
            }
          });
        }
        if (props.formData[item.fieldCode]?.length > 0) {
          props.formData[item.fieldCode].forEach(j => {
            columnList.push(deepClone(columnConfig));
          });
        }
        item.columnList = deepClone(columnList);
      } else if (item?.children?.length > 0) {
        getTableEachColumn(item.children);
      }
    });
  }
};

provide('formRef', formRef);
provide('formObj', formObj);
provide('isHidden', false);

defineExpose({
  validate
});
</script>

<style lang="less">
@import url('../design/style/form-design.less');
</style>
