<template>
  <div style="height: 500px">
    <custom-form
      ref="formbuilderDom"
      id="formbuilderDom"
      v-bind="formProps"
      @onLoad="onLoadForm"
    ></custom-form>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, reactive, nextTick, readonly } from 'vue';
import type { ICustomFormProps } from '@/views/FormBuilder/components/custom-form';
import { CustomForm } from '@/views/FormBuilder/components/custom-form';
import { useHttp } from '@crami/http';
import { message } from '@crami/ui';
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import { assign, isEmpty, isUndefined } from 'lodash-es';
import { useI18n } from '@crami/locale';
export default defineComponent({
  name: 'form-apply',
  components: { CustomForm },
  props: {
    componentProps: {
      type: Object,
    },
    height: { type: String },
  },
  setup(props, { expose }) {
    const { t } = useI18n();
    const {
      ObjectType = '',
      // ObjectID,
      TemplateId = '', //P_SYS_CUSTORM_DATA_74fc278e528c48da9359e349e55ea70b
      formModelPermissionList,
      taskId,
      processInstanceId,
    } = readonly(props.componentProps);
    let ObjectID = props.componentProps.ObjectID;
    dayjs.extend(utc);
    console.log('自定义表单参数', props);
    let applyUtils: any = null;
    // 分为新建，填报，只读模式
    const currentModel = ref(props.componentProps.currentModel);
    // 后台返回的表单数据结构
    const formDataSource = ref({});
    // 后台返回的表单模板的版本id
    const templateVersionId = ref('');
    // 后台返回的结构信息
    const formLayOutData = ref<any>({});
    const formbuilderDom = ref(null);

    // 表单所需参数
    const formProps = reactive<ICustomFormProps>({
      url: {
        images: '/form/build/images/',
        imageupload: 'image-upload-in-config-url',
      },
      pattern: 'applying', //'design','applying','view'
      data: formLayOutData.value, // applying模式需要有值
      toolbox: {}, // 映射关系
      height: props.height ? props.height : 500,
      isInit: false,
      language: localStorage.getItem('lang') || 'zhs',
      // 添加时区，默认 8
      timezone: parseInt(localStorage.getItem('TIME_ZONE')),
      systemInfo: {
        applicantDepartment: {
          text: localStorage.getItem('deptName'), // 申请人部门
          value: localStorage.getItem('userDept'),
        },
        applicantName: {
          text: localStorage.getItem('user_all_name'),
          value: localStorage.getItem('user_id'),
        }, // 申请人名称
        applicantPhoneNumber: localStorage.getItem('phone'), // 申请人手机号
        applicationDate: dayjs(new Date()).utc().format('YYYY-MM-DD HH:mm:ss'), // 申请日期
        processId: processInstanceId, // 流程id
        processSteps: taskId, // 流程步骤
        formNumber: ObjectID, // 表单编号
      },
    });

    // 表单验证
    const validate = () => {
      // 调用楠姐校验接口
      return new Promise(resolve => {
        resolve(formbuilderDom.value?.check());
      });
    };

    // 获取数据
    /*
      "formDataVariables": [
      {
          // 这里面的值是业务模型名称
          "formViewId": "BU_PR_CHANGE_MATER_EDIT_LISTVIEW",
          "dataVariables": [
            {
                "EID": "BU_PR_CHANGE_BILL_226af226d5e44512920217fcbfc9d864",
                "CREATEUID": "admin",
                "CREATETIME": "2022-09-19 17:37:30",
                "UPDATEUID": "admin",
            },
            {...}
          ]
      },
      {...}
      ]
    */
    const getData = () => {
      // 转换结构
      const MAINTABLEKEY = props.componentProps.ObjectType;
      const formData = applyUtils.formatSaveData(formbuilderDom.value?.getData());
      let dataSource = [];
      // 只组织主表数据， 从表数据后台不需要，暂不处理
      if (MAINTABLEKEY) {
        for (let [key, value] of Object.entries(formData)) {
          if (MAINTABLEKEY === key) {
            dataSource.push({
              formViewId: key,
              dataVariables: value,
            });
          }
        }
      }

      return dataSource;
    };

    // 表单数据保存
    const saveFormData = async () => {
      // 格式化数据
      // const formData = formatSaveData(formbuilderDom.value?.getData());

      const formData = applyUtils.formatSaveData(formbuilderDom.value?.getData());
      //默认新建为未发起状态
      formData[props.componentProps.ObjectType].FLOW_STATE = '6';
      let urlParams = {
        ObjectType,
        templateId: TemplateId,
        templateVersionId: templateVersionId.value,
        Data: JSON.stringify(formData),
        NewObject: currentModel.value === 'new', // 若为新建模式时，NewObject传true
        connect: localStorage.getItem('connect'),
        lang: localStorage.getItem('lang') || 'zhs',
        companyId: localStorage.getItem('companyId'),
        userId: localStorage.getItem('userId'),
      };
      console.log(
        '更新保存参数 :>> ',
        props.componentProps,
        props.componentProps.newVersion,
        ObjectID,
      );
      ObjectID = props.componentProps.ObjectID;
      // ObjectID在新建模式时不存在，非新建模式时存在
      if (ObjectID) {
        urlParams = assign(urlParams, {
          ObjectID: ObjectID,
          // 是否是新版本
          newVersion: props.componentProps.newVersion ? props.componentProps.newVersion : false,
        });
      }

      const objId = await useHttp({
        url: '/api/system/modelForm/saveFkObjectData',
        method: 'post',
        params: urlParams,
      }).then(
        res => {
          if (res.code === 200) {
            // 从data中解析
            const serverData = JSON.parse(res.data);
            if (serverData?.EID) {
              return serverData.EID;
            } else if (ObjectID) {
              return ObjectID;
            }
          } else {
            message.error(res.msg);
          }
        },
        () => {
          message.error(t('FormDesign.list.saveFailed'));
          return;
        },
      );
      return objId;
    };

    /**
     * 更新表单的流程状态
     *  流程发起成功或流程办理时调用，
     * 参数{ processInstanceId,taskId, approval }：processInstanceId发起的流程id,taskId节点Id,及approval流程状态标识
     */
    const setApprovalResult = (data: {
      processDefineId: string;
      processInstanceId: string;
      taskId?: string;
      approvalType: string;
      objId: string;
    }) => {
      console.log('==setApprovalResult 方法调用成功');
      return useHttp({
        url: '/api/system/modelForm/updateFormFlowInfo',
        method: 'post',
        params: {
          flowDefineId: data.processDefineId,
          flowInstanceId: data.processInstanceId,
          flowState: data.approvalType,
          objectId: data.objId,
          connect: localStorage.getItem('connect'),
          lang: localStorage.getItem('lang') || 'zhs',
          companyId: localStorage.getItem('companyId'),
        },
      });
    };

    // form加载完后获取表单结构
    const onLoadForm = async () => {
      if (!applyUtils) {
        applyUtils = formbuilderDom.value?.getApplyUtils();
      }
      // 此处的ObjectType和ObjectID是从工作流传入
      // 根据模式判断应该调用哪个初始化数据的接口
      // 前台编码暂定，后期可修改 new为新建模式，edit为填报模式，view为浏览模式，此处需要根据工作流传入的属性进行判断
      // 当前为新建模式
      if (currentModel.value === 'new') {
        // 获取表单结构, 只传ObjectType
        await getFormLayout({ type: ObjectType, templateId: TemplateId });
        // 获取新建的初始化数据
        await getNewModel(ObjectType);
      } else {
        // 编辑和预览模式
        // 获取表单结构, 需要传ObjectID和ObjectType
        await getFormLayout({ id: ObjectID, type: ObjectType, templateId: TemplateId });
        // 获取表单数据
        await getEditAndViewModel(ObjectID);
      }
    };

    // 获取新建模式下的初始化数据
    const getNewModel = async ObjectType => {
      const { code, data, msg } = await useHttp({
        url: '/api/system/modelForm/getForeignKeyInitData',
        method: 'post',
        params: {
          objectType: ObjectType,
          templateId: TemplateId,
          connect: localStorage.getItem('connect'),
          lang: localStorage.getItem('lang') || 'zhs',
          companyId: localStorage.getItem('companyId'),
        },
      });
      if (code == 200) {
        if (isEmpty(data)) {
          message.warning(t('FormDesign.common.noData'));
        } else {
          applyUtils.formatLoadData(data, formLayOutData.value);
        }
        // formatInitData({ serverDataObj: JSON.parse(data) });
        // 设置自定义表单数据源
        formProps.data = formLayOutData.value;
        // 格式化完数据后初始化自定义表单
        nextTick(() => {
          formbuilderDom.value?.init();
        });
      } else {
        message.error(msg);
      }
    };

    // 获取编辑和浏览模式下的初始化数据
    const getEditAndViewModel = async ObjectID => {
      const result = await useHttp({
        url: '/api/system/modelForm/getForeignKeyObject',
        method: 'post',
        params: {
          objectID: ObjectID,
          connect: localStorage.getItem('connect'),
          lang: localStorage.getItem('lang') || 'zhs',
          companyId: localStorage.getItem('companyId'),
        },
      });
      if (result.code == 200) {
        if (isEmpty(result.data)) {
          message.warning(t('FormDesign.common.noData'));
        } else {
          applyUtils.formatLoadData(result.data, formLayOutData.value);
        }
        // formatInitData({ serverDataObj: JSON.parse(result.data) });
        // 测试分页处理从表格式数据
        /* const data =
          '{"mainObjType":["MATERIALFORMAPPLY"],"MATERIALFORMAPPLY":["{\\"CREATEUID_DisplayValue\\":\\"\\",\\"CREATETIME_DisplayValue\\":\\"2022-10-13 09:40:57\\",\\"APPLYDEPT_DisplayValue\\":\\"\\",\\"DELFLAG_DisplayValue\\":\\"否\\",\\"APPLYTYPE_DisplayValue\\":\\"\\",\\"SERIALNUMBER_DisplayValue\\":\\"\\",\\"ECODE_DisplayValue\\":\\"111\\",\\"EID_DisplayValue\\":\\"MATERIALFORMAPPLY_5c530eb72e7f48a490b9b2e2aa6c16b7\\",\\"ECODE\\":\\"111\\",\\"CREATETIME\\":\\"2022-10-13 01:40:57.0\\",\\"DETAILSTRUCT_DisplayValue\\":\\"\\",\\"REMARK\\":\\"222\\",\\"YLHWH_DisplayValue\\":\\"\\",\\"DELFLAG\\":0,\\"EID\\":\\"MATERIALFORMAPPLY_5c530eb72e7f48a490b9b2e2aa6c16b7\\",\\"DETAILSTRUCT\\":\\"[]\\",\\"APPLYDATE_DisplayValue\\":\\"\\",\\"DELFLAG_DefaultValue\\":\\"0\\",\\"ENAME_DisplayValue\\":\\"\\",\\"APPLYDEPT\\":\\"\\",\\"REMARK_DisplayValue\\":\\"222\\",\\"APPLYUSER_DisplayValue\\":\\"\\",\\"ECOMPANYID\\":\\"P_SYS_COMPANY_155f6a331e804b69a6fc47e6273699fc\\",\\"ECOMPANYID_DisplayValue\\":\\"P_SYS_COMPANY_155f6a331e804b69a6fc47e6273699fc\\"}"],"MATERIALDETAIL_StartPosition":["16647777-4190-0077-f967-515d-e38c2904d053"],"MATERIALDETAIL":["{\\"PAGENUMEBR\\":\\"1\\",\\"MREMARK_DisplayValue\\":\\"666\\",\\"CREATEUID_DisplayValue\\":\\"\\",\\"APPLYPOST\\":\\"\\",\\"APPLYCOUNT_DisplayValue\\":\\"\\",\\"SERIALNUMBER\\":1,\\"CREATETIME_DisplayValue\\":\\"2022-10-13 09:40:57\\",\\"APPLYDEPT_DisplayValue\\":\\"\\",\\"DELFLAG_DisplayValue\\":\\"否\\",\\"APPLYORG\\":\\"\\",\\"MREMARK\\":\\"666\\",\\"SERIALNUMBER_DisplayValue\\":\\"1\\",\\"PAGENUMEBR_DisplayValue\\":\\"\\",\\"ECODE_DisplayValue\\":\\"\\",\\"EID_DisplayValue\\":\\"MATERIALDETAIL_14aea1b7412c4fab8dcb6ff8e73abbcf\\",\\"CREATETIME\\":\\"2022-10-13 01:40:57.0\\",\\"APPLYREASON_DisplayValue\\":\\"555\\",\\"APPLYCODE_DisplayValue\\":\\"\\",\\"DELFLAG\\":0,\\"EID\\":\\"MATERIALDETAIL_14aea1b7412c4fab8dcb6ff8e73abbcf\\",\\"APPLYORG_DisplayValue\\":\\"\\",\\"APPLYCUSTOMPAGE_DisplayValue\\":\\"\\",\\"APPLYROLE_DisplayValue\\":\\"\\",\\"GENDATE_DisplayValue\\":\\"\\",\\"DELFLAG_DefaultValue\\":\\"0\\",\\"APPLYPOST_DisplayValue\\":\\"\\",\\"MASTERID_DisplayValue\\":\\"MATERIALFORMAPPLY_5c530eb72e7f48a490b9b2e2aa6c16b7\\",\\"MASTERID\\":\\"MATERIALFORMAPPLY_5c530eb72e7f48a490b9b2e2aa6c16b7\\",\\"APPLYGROUP_DisplayValue\\":\\"\\",\\"APPLYREASON\\":\\"555\\",\\"ENAME_DisplayValue\\":\\"\\",\\"APPLYDEPT\\":\\"\\",\\"APPLYUSER_DisplayValue\\":\\"\\",\\"ECOMPANYID\\":\\"P_SYS_COMPANY_155f6a331e804b69a6fc47e6273699fc\\",\\"ECOMPANYID_DisplayValue\\":\\"P_SYS_COMPANY_155f6a331e804b69a6fc47e6273699fc\\",\\"APPLYGROUP\\":\\"\\"}"],"multi":[true]}';
        formatInitData({ serverDataObj: JSON.parse(data) }); */
        formProps.data = formLayOutData.value;
        // 格式化完数据后初始化自定义表单
        nextTick(() => {
          formbuilderDom.value?.init();
        });
      }
    };

    // 获取表单结构
    const getFormLayout = async (obj: { id?: string; type: string; templateId: string }) => {
      const { code, data, msg } = await useHttp({
        url: '/api/system/modelForm/getFormlayoutData',
        method: 'post',
        params: {
          ObjectID: obj.id,
          ObjType: obj.type,
          templateId: obj.templateId,
          connect: localStorage.getItem('connect'),
          lang: localStorage.getItem('lang') || 'zhs',
          companyId: localStorage.getItem('companyId'),
        },
      });
      if (code == 200) {
        // 权限处理逻辑  权限列表
        if (isEmpty(data)) {
          message.warning(t('FormDesign.common.noData'));
          return;
        }
        templateVersionId.value = data.versionId;
        formLayOutData.value = JSON.parse(data.layoutData);
        if (formbuilderDom.value) {
          // 获取表单值映射关系
          if (formLayOutData.value.controls) {
            // 组织自定义表单需要的toolbox配置项
            // formbuilderDom.value.loadFileData(formLayOutData.value);
            //  处理权限逻辑，非新建流程
            if (currentModel.value === 'edit') {
              if (!isUndefined(formModelPermissionList)) {
                // 获取主表权限
                const mainTableAuthor = formModelPermissionList.filter(
                  item => item.viewName === ObjectType,
                );
                // 获取从表权限
                const childTableData = formModelPermissionList.filter(
                  item => item.viewName !== ObjectType,
                );
                // 填报模式所有数据根据权限设定
                formLayOutData.value?.controls.forEach(item => {
                  if (!isUndefined(item.tag)) {
                    // 主表
                    if (item.tag.Master) {
                      //labelValue类型的不进行权限操作
                      if (item.tag.DisposeType !== 'LabelValue') {
                        const itemPermission = getFieldPermissionData(
                          mainTableAuthor[0].formFieldList,
                          item.tag.InfoType,
                        );
                        // modelEdit 值为1时是可编辑，为0时是不可编辑，为-1时是表中有的字段是可编辑有的是不可编辑的
                        if (mainTableAuthor[0].modelEdit === '1') {
                          item.readonly = false;
                        } else {
                          item.readonly = itemPermission ? itemPermission.fieldEdit === '0' : true;
                        }

                        if (mainTableAuthor[0].modelRequired === '1') {
                          item.required = true;
                        } else {
                          item.required = itemPermission
                            ? itemPermission.fieldRequired === '1'
                            : false;
                        }
                      }
                    } else {
                      // 从表权限
                      childTableData.forEach(childItem => {
                        // 匹配从表表名
                        if (childItem.viewName === item.tag.ObjTypeName) {
                          //labelValue类型的不进行权限操作
                          if (item.tag?.DisposeType !== 'LabelValue') {
                            const itemPermission = getFieldPermissionData(
                              childItem.formFieldList,
                              item.tag.InfoType,
                            );
                            if (childItem.modelEdit === '1') {
                              item.readonly = false;
                            } else {
                              item.readonly = itemPermission
                                ? itemPermission.fieldEdit === '0'
                                : true;
                            }

                            if (childItem.modelRequired === '1') {
                              item.required = true;
                            } else {
                              item.required = itemPermission
                                ? itemPermission.fieldRequired === '1'
                                : false;
                            }
                          }
                        }
                      });
                    }
                  }
                });
              }
            } else if (currentModel.value === 'view') {
              // 预览模式所有数据只读
              formProps.pattern = 'view';
            }
            /* const toolBox = formLayOutData.value.controls.reduce((pre, cur) => {
              if (!isUndefined(cur.tag)) {
                // 根据展示类型设置
                pre[cur.type] = cloneDeep(linkObj[cur.tag.DisposeType]);
              }
              return pre;
            }, {}); */
            // 设置toolbox映射关系
            formProps.toolbox = applyUtils.generateToolbox(formLayOutData.value);
          }
        }
      } else {
        message.error(msg);
      }
    };
    // 获取表单-字段权限
    const getFieldPermissionData = (list: Array<any>, name: string) => {
      let result;
      if (list && list.length > 0) {
        result = list.find(item => item.formField === name);
        // if (result) {
        //   value = result[key];
        // }
      }
      return result;
    };

    expose({ validate, getData, saveFormData, setApprovalResult });

    return {
      formLayOutData,
      formDataSource,
      currentModel,
      formbuilderDom,
      formProps,
      onLoadForm,
      getData,
    };
  },
});
</script>
