package com.engine.secret.service.impl;

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSON;
import com.engine.core.impl.Service;
import com.engine.secret.entity.unpack.*;
import com.engine.secret.exception.CustomizeRunTimeException;
import com.engine.secret.service.UnpackZipService;
import com.engine.secret.util.ConfigUtil;
import com.engine.secret.util.FieldConvertUtil;
import com.engine.secret.util.FlowUtil;
import com.engine.secret.util.ModeUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.wbi.util.Util;
import com.weaver.formmodel.data.model.Formfield;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.model.FileHeader;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import weaver.conn.RecordSet;
import weaver.formmode.IgnoreCaseHashMap;
import weaver.general.BaseBean;
import weaver.systeminfo.SystemEnv;

import java.io.InputStream;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 离线数据包解析实现类
 *
 * @author:dxfeng
 * @createTime: 2025/03/26
 * @version: 1.0
 */
public class OfflineZipUnpackServiceImpl extends Service implements UnpackZipService {

    /**
     * 解析类型，当前解析类，固定值为0
     */
    private static final String SOURCE_TYPE = "0";

    /**
     * 文件上传目录
     */
    private int uploadCatalogue;

    private Map<String, List<ApplicationResource>> applicationResourceMap;
    private Map<String, Map<String, ResourceInfo>> resourceInfoMap;
    private Map<String, FileHeader> fileHeaderMap;
    private String relatedFlowId;
    private final Map<String, Object> returnMap = new HashMap<>();
    private ZipFile zipFile;

    private final Map<String, Set<Integer>> insertTableMap = new ConcurrentHashMap<>();

    private final BaseBean baseBean = new BaseBean();

    @Override
    public Map<String, Object> registerAcceptance(ZipFile zipFile, UnpackParam unpackParam, JsonNode rootNode, Map<String, FileHeader> imageFileMap) {
        try {
            initializeResources(zipFile, unpackParam.getRequestId(), imageFileMap);
            insertDataAndFiles(rootNode, unpackParam);
        } catch (Exception e) {
            baseBean.writeLog(e);
            throw new CustomizeRunTimeException(e.getMessage());
        }
        returnMap.put("data", insertTableMap);
        return returnMap;
    }

    @Override
    public Map<String, Object> reviewResubmittedMaterials(ZipFile zipFile, String requestId, JsonNode rootNode, Map<String, FileHeader> imageFileMap) {
        try {
            initializeResources(zipFile, requestId, imageFileMap);
            updateCorrectedMaterials(rootNode);
        } catch (Exception e) {
            baseBean.writeLog(e);
            throw new CustomizeRunTimeException(e);
        }
        return returnMap;
    }

    @Override
    public Map<String, Object> deleteParsedData(Map<String, Object> param) {
        String requestId = Util.null2String(param.get("requestId"));
        String isCorrection = Util.null2String(param.get("isCorrection"));

        // 读取配置表
        RecordSet rs = new RecordSet();
        List<DataConfig> dataConfig = getDataConfig("0");

        if ("true".equals(isCorrection)) {
            // 补正
        } else {
            // 非补正
            for (DataConfig config : dataConfig) {
                String mainTableName = config.getMainTableName();
                String relatedField = config.getRelatedField();
                List<DataConfig> childDataConfig = config.getChildDataConfig();

                String sql = "select id from " + mainTableName + " where " + relatedField + " =?";
                rs.executeQuery(sql, requestId);
                if (rs.next()) {
                    int billId = rs.getInt("id");
                    if (billId < 0) {
                        continue;
                    }
                    // 删除明细表数据
                    for (DataConfig childConfig : childDataConfig) {
                        String detailTableName = childConfig.getDetailTableName();
                        rs.executeUpdate("delete from " + detailTableName + " where mainid = ?", billId);
                    }
                    // 删除主表数据
                    rs.executeUpdate("delete from " + mainTableName + " where id = ?", billId);
                }
            }

        }
        return null;
    }

    /**
     * 初始化全局变量数据
     *
     * @param zipFile
     * @param requestId
     * @param imageFileMap
     */
    private void initializeResources(ZipFile zipFile, String requestId, Map<String, FileHeader> imageFileMap) {
        this.fileHeaderMap = imageFileMap;
        this.relatedFlowId = requestId;
        this.zipFile = zipFile;
    }


    /**
     * 更新补正文件
     *
     * @param rootNode
     * @throws Exception
     */
    private void updateCorrectedMaterials(JsonNode rootNode) throws Exception {
        initializeUploadCatalogue();
        List<DataConfig> dataConfigList = getDataConfig(SOURCE_TYPE);
        baseBean.writeLog("dataConfigList==" + JSON.toJSONString(dataConfigList));

        initializeResourceMaps(rootNode);

        if (CollectionUtils.isNotEmpty(dataConfigList)) {
            processDataConfigForUpdate(dataConfigList);
        }
    }

    /**
     * 初始化文件上传目录
     */
    private void initializeUploadCatalogue() {
        String uploadCatalogueStr = ConfigUtil.getConfig("UPLOAD_CATALOGUE");
        if (StringUtils.isBlank(uploadCatalogueStr)) {
            throw new CustomizeRunTimeException("未获取到解析文件目录设置,检查配置[uf_config]");
        }
        uploadCatalogue = Convert.toInt(uploadCatalogueStr, -1);
        baseBean.writeLog("uploadCatalogue==" + uploadCatalogue);
    }

    /**
     * 解析JSON文件，构建applicationResourceMap、resourceInfoMap
     *
     * @param rootNode
     */
    private void initializeResourceMaps(JsonNode rootNode) {
        List<ApplicationResource> applicationResourceList = getApplicationResourceList(rootNode);
        applicationResourceMap = applicationResourceList.stream()
                .collect(Collectors.groupingBy(ApplicationResource::getFid));
        baseBean.writeLog("applicationResourceMap==" + JSON.toJSONString(applicationResourceMap));

        List<ResourceInfo> resourceInfoList = getResourceInfoList(rootNode);
        resourceInfoMap = resourceInfoList.stream()
                .collect(Collectors.groupingBy(ResourceInfo::getVirtualPath,
                        Collectors.toMap(ResourceInfo::getId, item -> item)));
        baseBean.writeLog("resourceInfoMap==" + JSON.toJSONString(resourceInfoMap));
    }

    /**
     * 更新主表补正文件数据
     *
     * @param dataConfigList
     * @throws Exception
     */
    private void processDataConfigForUpdate(List<DataConfig> dataConfigList) throws Exception {
        RecordSet rs = new RecordSet();
        for (DataConfig dataConfig : dataConfigList) {
            String mainTableName = dataConfig.getMainTableName();
            String relatedField = dataConfig.getRelatedField();
            String rootPath = dataConfig.getRootPath();
            baseBean.writeLog("rootPath==" + rootPath);

            List<DataConfig> childDataConfigList = dataConfig.getChildDataConfig();
            List<DataConfigDetail> fieldDetailList = dataConfig.getDetailList();
            List<FileConfig> fileList = dataConfig.getFileList();

            if (CollectionUtils.isNotEmpty(fieldDetailList)) {
                String sql = "select id from " + mainTableName + " where " + relatedField + " =?";
                rs.executeQuery(sql, relatedFlowId);
                if (rs.next()) {
                    int billId = rs.getInt("id");
                    if (billId < 0) {
                        continue;
                    }

                    updateFileList(billId, fileList, mainTableName, false);

                    if (CollectionUtils.isNotEmpty(childDataConfigList)) {
                        processChildDataConfigForUpdate(billId, childDataConfigList);
                    }
                }
            }
        }
    }

    /**
     * 更新明细表补正文件数据
     *
     * @param billId
     * @param childDataConfigList
     * @throws Exception
     */
    private void processChildDataConfigForUpdate(int billId, List<DataConfig> childDataConfigList) throws
            Exception {
        for (DataConfig childDataConfig : childDataConfigList) {
            String detailTableName = childDataConfig.getDetailTableName();
            List<FileConfig> childFileList = childDataConfig.getFileList();

            if (CollectionUtils.isNotEmpty(childFileList)) {
                baseBean.writeLog("开始解析文件，写入明细数据");
                updateFileList(billId, childFileList, detailTableName, true);
            }
        }
    }

    /**
     * 文件列表更新
     *
     * @param mainId
     * @param fileConfigList
     * @param tableName
     * @param isDetail
     * @throws Exception
     */
    private void updateFileList(int mainId, List<FileConfig> fileConfigList, String tableName, boolean isDetail) throws Exception {
        Map<String, Object> dataMap = new HashMap<String, Object>();
        String fileTypeField = "";
        String fileTypeValue = "";

        for (FileConfig fileConfig : fileConfigList) {
            String fieldName = fileConfig.getFieldName();
            String fileId = fileConfig.getFileId();
            String fixedValue = fileConfig.getFixedValue();
            String attachments = fileConfig.getAttachments();

            if (StringUtils.isNotBlank(fixedValue)) {
                continue;
            }

            if (StringUtils.isNotBlank(attachments)) {
                fileTypeField = fieldName;
                fileTypeValue = attachments;
                continue;
            }

            if (!"2".equals(fileConfig.getIsFilled())) {
                continue;
            }

            List<ApplicationResource> applicationResources = applicationResourceMap.get(fileId);
            if (CollectionUtils.isEmpty(applicationResources)) {
                baseBean.writeLog("根据fid未获取到数据，fileId==" + fileId);
                continue;
            }

            Map<String, ResourceInfo> fileResourceMap = resourceInfoMap.get(fileConfig.getIsFilled());
            if (fileResourceMap == null || fileResourceMap.isEmpty()) {
                baseBean.writeLog("根据文件类型未获取到数据，isFilled==" + fileConfig.getIsFilled());
                continue;
            }

            List<Integer> docIds = processFileResources(applicationResources, fileResourceMap);
            if (!docIds.isEmpty()) {
                dataMap.put(fieldName, StringUtils.join(docIds, ","));
            }
        }

        if (dataMap.isEmpty() || StringUtils.isBlank(fileTypeField) || StringUtils.isBlank(fileTypeValue)) {
            baseBean.writeLog("dataMap.size==" + dataMap.size());
            baseBean.writeLog("fileTypeField==" + fileTypeField);
            baseBean.writeLog("fileTypeValue==" + fileTypeValue);
            return;
        }

        baseBean.writeLog("文件更新集合，dataMap==" + JSON.toJSONString(dataMap));
        updateData(mainId, dataMap, tableName, isDetail, fileTypeField, fileTypeValue);
    }

    /**
     * 上传对应的文件，返回docId集合
     *
     * @param applicationResources
     * @param fileResourceMap
     * @return
     * @throws Exception
     */
    private List<Integer> processFileResources(List<ApplicationResource> applicationResources,
                                               Map<String, ResourceInfo> fileResourceMap) throws Exception {
        List<Integer> docIds = new ArrayList<>();

        for (ApplicationResource resource : applicationResources) {
            ResourceInfo resourceInfo = fileResourceMap.get(resource.getRid());
            if (resourceInfo == null) {
                baseBean.writeLog("根据文件rid未获取到数据，rid==" + resource.getRid());
                continue;
            }

            int imageFileId = generateImageFileId(zipFile, fileHeaderMap.get(resourceInfo.getFileName()),
                    resourceInfo.getFileName());
            int docId = ModeUtil.createDocId(uploadCatalogue, imageFileId, user);
            docIds.add(docId);
        }

        return docIds;
    }


    /**
     * 更新补正文件数据
     *
     * @param mainId
     * @param dataMap
     * @param tableName
     * @param isDetail
     * @param fileTypeField
     * @param fileTypeValue
     */
    private void updateData(int mainId, Map<String, Object> dataMap, String tableName,
                            boolean isDetail, String fileTypeField, String fileTypeValue) {
        if (isDetail) {
            //dataMap.put("mainid", mainId);
            String whereSql = " where mainid = " + mainId + " and " + fileTypeField + "=" + fileTypeValue;
            baseBean.writeLog("whereSql===" + whereSql);
            ModeUtil.updateData(dataMap, tableName, whereSql);
        } else {
            dataMap.put("id", mainId);
            ModeUtil.updateDataById(dataMap, tableName);
        }
    }

    /**
     * 插入数据和文件
     *
     * @param rootNode
     * @throws Exception
     */
    private void insertDataAndFiles(JsonNode rootNode, UnpackParam unpackParam) throws Exception {
        initializeUploadCatalogue();
        List<DataConfig> dataConfigList = getDataConfig(SOURCE_TYPE);
        baseBean.writeLog("dataConfigList==" + JSON.toJSONString(dataConfigList));

        checkDatas(dataConfigList, rootNode, unpackParam);
        initializeResourceMaps(rootNode);

        if (CollectionUtils.isNotEmpty(dataConfigList)) {
            processDataConfigForInsert(rootNode, dataConfigList);
        }
    }

    /**
     * 校验数据是否一致
     *
     * @param dataConfigList
     * @param rootNode
     * @param unpackParam
     * @throws Exception
     */
    private void checkDatas(List<DataConfig> dataConfigList, JsonNode rootNode, UnpackParam unpackParam) throws Exception {
        // 字段校验
        List<CheckFields> checkFields = unpackParam.getCheckFields();
        String requestId = unpackParam.getRequestId();
        Map<String, DataConfig> dataConfigMap = dataConfigList.stream().collect(Collectors.toMap(DataConfig::getMainTableName, item -> item, (k1, k2) -> k1));
        for (CheckFields checkField : checkFields) {
            DataConfig dataConfig = dataConfigMap.get(checkField.getName());


            String fields = checkField.getFields();
            String formFields = checkField.getFormFields();
            if (StringUtils.isNotBlank(fields) && StringUtils.isNotBlank(formFields)) {
                String[] fieldArray = fields.split(",");
                String[] formFieldsArray = formFields.split(",");
                if (fieldArray.length != formFieldsArray.length) {
                    throw new CustomizeRunTimeException("表单校验参数格式错误");
                }
                List<Formfield> formFieldList = ModeUtil.getFieldList(dataConfig.getMainTableName());
                Map<String, Formfield> mainTableFieldMap = formFieldList.stream()
                        .filter(item -> item.getViewtype() == 0)
                        .collect(Collectors.toMap(Formfield::getFieldname,
                                item -> item, (k1, k2) -> k1));

                String tableNameByRequestId = FlowUtil.getTableNameByRequestId(requestId);
                RecordSet rs = new RecordSet();
                rs.executeQuery("select * from " + tableNameByRequestId + " where requestId = ?", requestId);

                IgnoreCaseHashMap<String, Object> flowDataMap = ModeUtil.getSingleRecordMap(rs);

                // 根据根结点，获取配置
                String rootPath = dataConfig.getRootPath();
                JsonNode checkNode;
                if (StringUtils.isBlank(rootPath)) {
                    checkNode = rootNode;
                } else {
                    checkNode = rootNode.get(rootPath);
                }
                if (null == checkNode) {
                    throw new CustomizeRunTimeException("未获取到根结点数据[" + rootPath + "]");
                }

                List<DataConfigDetail> detailList = dataConfig.getDetailList();
                Map<String, DataConfigDetail> configDetailMap = detailList.stream().collect(Collectors.toMap(DataConfigDetail::getFieldName, item -> item, (k1, k2) -> k1));
                for (int i = 0; i < fieldArray.length; i++) {
                    String field = fieldArray[i];
                    String formField = formFieldsArray[i];
                    boolean check = processFieldForCheck(checkNode, configDetailMap.get(field), mainTableFieldMap, Util.null2String(flowDataMap.get(formField)));
                    if (!check) {
                        Formfield formfield = mainTableFieldMap.get(field);
                        throw new CustomizeRunTimeException("[" + SystemEnv.getHtmlLabelName(formfield.getFieldlabel(), user.getLanguage()) + "]字段校验不通过，表单填写内容与解析包对应内容不一致");
                    }
                }
            }
        }
    }

    /**
     * 解析配置表
     *
     * @param rootNode
     * @param dataConfigList
     * @throws Exception
     */
    private void processDataConfigForInsert(JsonNode rootNode, List<DataConfig> dataConfigList) throws Exception {
        for (DataConfig dataConfig : dataConfigList) {
            String mainTableName = dataConfig.getMainTableName();
            String relatedField = dataConfig.getRelatedField();
            String rootPath = dataConfig.getRootPath();
            baseBean.writeLog("rootPath==" + rootPath);

            List<DataConfigDetail> fieldDetailList = dataConfig.getDetailList();
            List<DataConfig> childDataConfigList = dataConfig.getChildDataConfig();
            List<FileConfig> fileList = dataConfig.getFileList();

            List<Formfield> formFieldList = ModeUtil.getFieldList(mainTableName);
            Map<String, Formfield> mainTableFieldMap = formFieldList.stream()
                    .filter(item -> item.getViewtype() == 0)
                    .collect(Collectors.toMap(Formfield::getFieldname,
                            item -> item, (k1, k2) -> k1));

            if (CollectionUtils.isNotEmpty(fieldDetailList)) {
                processRootPath(rootNode, mainTableName, relatedField, fieldDetailList,
                        mainTableFieldMap, childDataConfigList, formFieldList, fileList, rootPath);
            }
        }
    }

    /**
     * 根据根路径配置，判断处理方式
     *
     * @param rootNode
     * @param mainTableName
     * @param relatedField
     * @param fieldDetailList
     * @param mainTableFieldMap
     * @param childDataConfigList
     * @param formFieldList
     * @param fileList
     * @param rootPath
     * @throws Exception
     */
    private void processRootPath(JsonNode rootNode, String mainTableName, String relatedField,
                                 List<DataConfigDetail> fieldDetailList, Map<String, Formfield> mainTableFieldMap,
                                 List<DataConfig> childDataConfigList, List<Formfield> formFieldList,
                                 List<FileConfig> fileList, String rootPath) throws Exception {
        if (StringUtils.isNotBlank(rootPath)) {
            if (rootPath.contains("[*]")) {
                processArrayRootPath(rootNode, mainTableName, relatedField, fieldDetailList,
                        mainTableFieldMap, childDataConfigList, formFieldList,
                        fileList, rootPath);
            } else {
                processSingleRootPath(rootNode, mainTableName, relatedField, fieldDetailList,
                        mainTableFieldMap, childDataConfigList, formFieldList,
                        fileList, rootPath);
            }
        } else {
            processRootNode(rootNode, mainTableName, relatedField, fieldDetailList,
                    mainTableFieldMap, childDataConfigList, formFieldList, fileList);
        }
    }

    /**
     * 处理数组数据
     *
     * @param rootNode
     * @param mainTableName
     * @param relatedField
     * @param fieldDetailList
     * @param mainTableFieldMap
     * @param childDataConfigList
     * @param formFieldList
     * @param fileList
     * @param rootPath
     * @throws Exception
     */
    private void processArrayRootPath(JsonNode rootNode, String mainTableName, String relatedField,
                                      List<DataConfigDetail> fieldDetailList, Map<String, Formfield> mainTableFieldMap,
                                      List<DataConfig> childDataConfigList, List<Formfield> formFieldList,
                                      List<FileConfig> fileList, String rootPath) throws Exception {
        String path = rootPath.replace("[*]", "");
        JsonNode jsonNode = rootNode.at(path);

        if (jsonNode == null) {
            throw new CustomizeRunTimeException("数据解析失败，未找到对应字段:[" + path + "]");
        }
        if (!jsonNode.isArray()) {
            throw new CustomizeRunTimeException("数据解析失败，未找到对应字段集合:[" + path + "]");
        }
        Set<Integer> tableIdList = getTableIdList(mainTableName);
        for (JsonNode node : jsonNode) {
            int billId = insertMainTable(node, mainTableName, relatedField, fieldDetailList, mainTableFieldMap);
            if (billId < 0) {
                continue;
            }
            tableIdList.add(billId);
            dealDetailData(rootNode, billId, childDataConfigList, formFieldList);
            dealFileList(billId, fileList, mainTableName, false);
        }
    }

    /**
     * 处理单节点数据
     *
     * @param rootNode
     * @param mainTableName
     * @param relatedField
     * @param fieldDetailList
     * @param mainTableFieldMap
     * @param childDataConfigList
     * @param formFieldList
     * @param fileList
     * @param rootPath
     * @throws Exception
     */
    private void processSingleRootPath(JsonNode rootNode, String mainTableName, String relatedField,
                                       List<DataConfigDetail> fieldDetailList, Map<String, Formfield> mainTableFieldMap,
                                       List<DataConfig> childDataConfigList, List<Formfield> formFieldList,
                                       List<FileConfig> fileList, String rootPath) throws Exception {
        JsonNode jsonNode = rootNode.at(rootPath);
        int billId = insertMainTable(jsonNode, mainTableName, relatedField, fieldDetailList, mainTableFieldMap);
        if (billId < 0) {
            return;
        }
        getTableIdList(mainTableName).add(billId);
        dealDetailData(rootNode, billId, childDataConfigList, formFieldList);
        dealFileList(billId, fileList, mainTableName, false);
    }

    /**
     * 处理完整节点数据
     *
     * @param rootNode
     * @param mainTableName
     * @param relatedField
     * @param fieldDetailList
     * @param mainTableFieldMap
     * @param childDataConfigList
     * @param formFieldList
     * @param fileList
     * @throws Exception
     */
    private void processRootNode(JsonNode rootNode, String mainTableName, String relatedField,
                                 List<DataConfigDetail> fieldDetailList, Map<String, Formfield> mainTableFieldMap,
                                 List<DataConfig> childDataConfigList, List<Formfield> formFieldList,
                                 List<FileConfig> fileList) throws Exception {

        int billId = insertMainTable(rootNode, mainTableName, relatedField, fieldDetailList, mainTableFieldMap);
        if (billId < 0) {
            return;
        }
        getTableIdList(mainTableName).add(billId);
        dealDetailData(rootNode, billId, childDataConfigList, formFieldList);
        dealFileList(billId, fileList, mainTableName, false);
    }

    /**
     * 处理明细表数据
     *
     * @param rootNode
     * @param mainId
     * @param childDataConfigList
     * @param formFieldList
     * @throws Exception
     */
    private void dealDetailData(JsonNode rootNode, int mainId, List<DataConfig> childDataConfigList,
                                List<Formfield> formFieldList) throws Exception {
        if (CollectionUtils.isEmpty(childDataConfigList)) {
            return;
        }

        for (DataConfig childDataConfig : childDataConfigList) {
            String detailTableName = childDataConfig.getDetailTableName();
            Map<String, Formfield> detailTableFieldMap = formFieldList.stream()
                    .filter(item -> detailTableName.equals(item.getDetailtable()))
                    .collect(Collectors.toMap(Formfield::getFieldname,
                            item -> item, (k1, k2) -> k1));

            List<DataConfigDetail> fieldList = childDataConfig.getDetailList();
            List<FileConfig> fileList = childDataConfig.getFileList();

            if (CollectionUtils.isNotEmpty(fileList)) {
                baseBean.writeLog("开始解析文件，写入明细数据");
                dealFileList(mainId, fileList, detailTableName, true);
            } else {
                processDetailRootPath(rootNode, detailTableName, mainId, fieldList, detailTableFieldMap,
                        childDataConfig.getRootPath());
            }
        }
    }

    /**
     * 根据明细表根路径配置，判断处理方式
     *
     * @param rootNode
     * @param detailTableName
     * @param mainId
     * @param fieldList
     * @param detailTableFieldMap
     * @param rootPath
     * @throws Exception
     */
    private void processDetailRootPath(JsonNode rootNode, String detailTableName, int mainId,
                                       List<DataConfigDetail> fieldList, Map<String, Formfield> detailTableFieldMap,
                                       String rootPath) throws Exception {
        if (StringUtils.isNotBlank(rootPath)) {
            if (rootPath.contains("[*]")) {
                processDetailArrayRootPath(rootNode, detailTableName, mainId, fieldList,
                        detailTableFieldMap, rootPath);
            } else {
                processDetailSingleRootPath(rootNode, detailTableName, mainId, fieldList,
                        detailTableFieldMap, rootPath);
            }
        } else {
            insertDetailTable(rootNode, detailTableName, mainId, fieldList, detailTableFieldMap);
        }
    }

    /**
     * 处理明细表数据数据
     *
     * @param rootNode
     * @param detailTableName
     * @param mainId
     * @param fieldList
     * @param detailTableFieldMap
     * @param rootPath
     * @throws Exception
     */
    private void processDetailArrayRootPath(JsonNode rootNode, String detailTableName, int mainId,
                                            List<DataConfigDetail> fieldList, Map<String, Formfield> detailTableFieldMap,
                                            String rootPath) throws Exception {
        String path = rootPath.replace("[*]", "");
        JsonNode jsonNode = rootNode.at(path);

        if (jsonNode == null) {
            throw new CustomizeRunTimeException("数据解析失败，未找到对应字段:[" + path + "]");
        }
        if (!jsonNode.isArray()) {
            throw new CustomizeRunTimeException("数据解析失败，未找到对应字段集合:[" + path + "]");
        }

        for (JsonNode node : jsonNode) {
            insertDetailTable(node, detailTableName, mainId, fieldList, detailTableFieldMap);
        }
    }

    /**
     * 处理明细表单节点数据
     *
     * @param rootNode
     * @param detailTableName
     * @param mainId
     * @param fieldList
     * @param detailTableFieldMap
     * @param rootPath
     * @throws Exception
     */
    private void processDetailSingleRootPath(JsonNode rootNode, String detailTableName, int mainId,
                                             List<DataConfigDetail> fieldList, Map<String, Formfield> detailTableFieldMap,
                                             String rootPath) throws Exception {
        JsonNode jsonNode = rootNode.at(rootPath);
        insertDetailTable(jsonNode, detailTableName, mainId, fieldList, detailTableFieldMap);
    }

    /**
     * 插入主表数据
     *
     * @param jsonNode
     * @param mainTableName
     * @param relatedField
     * @param fieldList
     * @param mainTableFieldMap
     * @return
     * @throws Exception
     */
    private int insertMainTable(JsonNode jsonNode, String mainTableName, String relatedField,
                                List<DataConfigDetail> fieldList, Map<String, Formfield> mainTableFieldMap) throws Exception {
        Map<String, Object> insertMap = new HashMap<String, Object>();

        for (DataConfigDetail fieldDetail : fieldList) {
            processFieldForInsert(jsonNode, insertMap, fieldDetail, mainTableFieldMap);
        }

        if (insertMap.isEmpty()) {
            return -1;
        }

        if (StringUtils.isNotBlank(relatedField)) {
            insertMap.put(relatedField, relatedFlowId);
        }

        String uuid = UUID.randomUUID().toString();
        insertMap.put("modeuuid", uuid);
        int formModeId = ModeUtil.getModeIdByTableName(mainTableName);
        insertMap.put("formmodeid", formModeId);

        ModeUtil.buildModeInsertFields(insertMap, user.getUID());
        baseBean.writeLog("insertMainTable: " + JSON.toJSONString(insertMap));

        ModeUtil.insertData(insertMap, mainTableName);
        return ModeUtil.refreshRight(uuid, mainTableName, formModeId, user.getUID());
    }

    /**
     * 构建待插入数据的字段集合
     *
     * @param jsonNode
     * @param insertMap
     * @param fieldDetail
     * @param fieldMap
     * @throws Exception
     */
    private boolean processFieldForInsert(JsonNode jsonNode, Map<String, Object> insertMap,
                                          DataConfigDetail fieldDetail, Map<String, Formfield> fieldMap) throws Exception {
        String fieldName = fieldDetail.getFieldName();
        JsonNode atNode = jsonNode.at(fieldDetail.getPath());

        if (atNode != null) {
            String value = atNode.asText();
            if (StringUtils.isNotBlank(fieldDetail.getCondition()) && !value.equals(fieldDetail.getCondition())) {
                return true;
            }

            Formfield formfield = fieldMap.get(fieldName.toLowerCase());
            if (formfield == null) {
                return false;
            }

            Object reallyValue = getFieldValue(fieldDetail, value, formfield);
            insertMap.put(fieldName, reallyValue);
        }
        return false;
    }

    /**
     * 构建待校验数据的字段集合
     *
     * @param jsonNode
     * @param fieldDetail
     * @param fieldMap
     * @return
     * @throws Exception
     */
    private boolean processFieldForCheck(JsonNode jsonNode, DataConfigDetail fieldDetail, Map<String, Formfield> fieldMap,String flowData) throws Exception {
        String fieldName = fieldDetail.getFieldName();
        JsonNode atNode = jsonNode.at(fieldDetail.getPath());

        if (atNode != null) {
            String value = atNode.asText();
            if (StringUtils.isNotBlank(fieldDetail.getCondition()) && !value.equals(fieldDetail.getCondition())) {
                return false;
            }

            Formfield formfield = fieldMap.get(fieldName.toLowerCase());
            if (formfield == null) {
                return false;
            }

            return flowData.equals(Util.null2String(getFieldValue(fieldDetail, value, formfield)));
        }
        return false;
    }

    /**
     * 字段值转换，转换为数据库中对应的实际值
     *
     * @param fieldDetail
     * @param value
     * @param formfield
     * @return
     * @throws Exception
     */
    private Object getFieldValue(DataConfigDetail fieldDetail, String value, Formfield formfield) throws Exception {
        if (StringUtils.isNotBlank(fieldDetail.getConvertSql())) {
            return FieldConvertUtil.executeConvertSql(fieldDetail.getConvertSql(), value);
        }
        return FieldConvertUtil.getReallyValue(formfield, value);
    }

    /**
     * 插入明细表数据
     *
     * @param jsonNode
     * @param detailTableName
     * @param mainId
     * @param fieldList
     * @param detailTableFieldMap
     * @throws Exception
     */
    private void insertDetailTable(JsonNode jsonNode, String detailTableName, int mainId,
                                   List<DataConfigDetail> fieldList, Map<String, Formfield> detailTableFieldMap) throws Exception {
        Map<String, Object> insertMap = new HashMap<String, Object>();

        for (DataConfigDetail fieldDetail : fieldList) {
            boolean isReturn = processFieldForInsert(jsonNode, insertMap, fieldDetail, detailTableFieldMap);
            if (isReturn) {
                return;
            }
        }

        if (insertMap.isEmpty()) {
            return;
        }

        insertMap.put("mainId", mainId);
        baseBean.writeLog("insertDetailTable: " + JSON.toJSONString(insertMap));
        ModeUtil.insertData(insertMap, detailTableName);
    }

    /**
     * 处理文件列表
     *
     * @param mainId
     * @param fileConfigList
     * @param tableName
     * @param isDetail
     * @throws Exception
     */
    private void dealFileList(int mainId, List<FileConfig> fileConfigList, String tableName, boolean isDetail) throws
            Exception {
        Map<String, Object> dataMap = new HashMap<String, Object>();
        Map<String, Object> defaultDataMap = new HashMap<String, Object>();

        for (FileConfig fileConfig : fileConfigList) {
            processFileConfig(fileConfig, dataMap, defaultDataMap);
        }

        if (dataMap.isEmpty()) {
            baseBean.writeLog("dataMap集合为空");
            return;
        }

        dataMap.putAll(defaultDataMap);
        baseBean.writeLog("文件插入集合，dataMap==" + JSON.toJSONString(dataMap));

        if (isDetail) {
            dataMap.put("mainid", mainId);
            ModeUtil.insertData(dataMap, tableName);
        } else {
            dataMap.put("id", mainId);
            ModeUtil.updateDataById(dataMap, tableName);
        }
    }

    /**
     * 根据文件配置，构建数据集合
     *
     * @param fileConfig
     * @param dataMap
     * @param defaultDataMap
     * @throws Exception
     */
    private void processFileConfig(FileConfig fileConfig, Map<String, Object> dataMap,
                                   Map<String, Object> defaultDataMap) throws Exception {
        String fieldName = fileConfig.getFieldName();
        String isFilled = fileConfig.getIsFilled();

        if ("2".equals(isFilled)) {
            return;
        }

        String fileId = fileConfig.getFileId();
        String fixedValue = fileConfig.getFixedValue();
        String attachments = fileConfig.getAttachments();

        if (StringUtils.isNotBlank(fixedValue)) {
            defaultDataMap.put(fieldName, fixedValue);
            return;
        }

        if (StringUtils.isNotBlank(attachments)) {
            defaultDataMap.put(fieldName, attachments);
            return;
        }

        List<ApplicationResource> applicationResources = applicationResourceMap.get(fileId);
        if (CollectionUtils.isEmpty(applicationResources)) {
            baseBean.writeLog("根据fid未获取到数据，fileId==" + fileId);
            return;
        }

        Map<String, ResourceInfo> fileResourceMap = resourceInfoMap.get(isFilled);
        if (fileResourceMap == null || fileResourceMap.isEmpty()) {
            baseBean.writeLog("根据文件类型未获取到数据，isFilled==" + isFilled);
            return;
        }

        List<Integer> docIds = processFileResources(applicationResources, fileResourceMap);
        if (!docIds.isEmpty()) {
            dataMap.put(fieldName, StringUtils.join(docIds, ","));
        }
    }

    /**
     * 获取配置主项
     *
     * @param type
     * @return
     */
    private List<DataConfig> getDataConfig(String type) {
        List<DataConfig> dataConfigList = new ArrayList<>();
        RecordSet rs = new RecordSet();
        rs.executeQuery("select * from " + QualificationApplicationServiceImpl.CONFIG_TABLE_NAME + " where main_table is not null and source_type = ?", type);

        while (rs.next()) {
            DataConfig dataConfig = buildDataConfig(rs);
            dataConfig.setDetailList(getDetailList(dataConfig.getId()));
            dataConfig.setFileList(getFileList(dataConfig.getId()));

            String detailTableName = dataConfig.getDetailTableName();
            if (StringUtils.isNotBlank(detailTableName)) {
                dataConfig.setChildDataConfig(getChildDataConfig(detailTableName, type));
            }

            dataConfigList.add(dataConfig);
        }
        return dataConfigList;
    }

    /**
     * 构建DataConfig对象
     *
     * @param rs
     * @return
     * @throws RuntimeException
     */
    private DataConfig buildDataConfig(RecordSet rs) throws RuntimeException {
        DataConfig dataConfig = new DataConfig();
        dataConfig.setId(rs.getString("id"));
        dataConfig.setMainTableName(rs.getString("main_table"));
        dataConfig.setRelatedField(rs.getString("related_field"));
        dataConfig.setDetailTableName(rs.getString("detail_tables"));
        dataConfig.setRootPath(rs.getString("root_path"));
        return dataConfig;
    }

    /**
     * 构建明细表配置项集合
     *
     * @param detailTableName
     * @param type
     * @return
     */
    private List<DataConfig> getChildDataConfig(String detailTableName, String type) {
        String[] detailNameArray = detailTableName.split(",");
        List<DataConfig> dataConfigList = new ArrayList<>();

        for (String dtName : detailNameArray) {
            RecordSet rs = new RecordSet();
            rs.executeQuery("select * from " + QualificationApplicationServiceImpl.CONFIG_TABLE_NAME + " where main_table is null and detail_tables = ? and source_type = ?", dtName, type);

            while (rs.next()) {
                DataConfig dataConfig = new DataConfig();
                dataConfig.setId(rs.getString("id"));
                dataConfig.setDetailTableName(rs.getString("detail_tables"));
                dataConfig.setRootPath(rs.getString("root_path"));
                dataConfig.setDetailList(getDetailList(dataConfig.getId()));
                dataConfig.setFileList(getFileList(dataConfig.getId()));
                dataConfigList.add(dataConfig);
            }
        }
        return dataConfigList;
    }

    /**
     * 获取字段配置对照关系集合
     *
     * @param mainId
     * @return
     */
    private List<DataConfigDetail> getDetailList(String mainId) {
        List<DataConfigDetail> detailList = new ArrayList<>();
        RecordSet rs = new RecordSet();
        rs.executeQuery("select * from " + QualificationApplicationServiceImpl.CONFIG_DETAIL_TABLE_NAME + " where mainId = ?", mainId);

        while (rs.next()) {
            detailList.add(DataConfigDetail.builder()
                    .fieldName(rs.getString("field_name"))
                    .path(rs.getString("config_path"))
                    .condition(rs.getString("conditions"))
                    .convertSql(rs.getString("convert_sql"))
                    .build());
        }
        return detailList;
    }

    /**
     * 获取文件配置对照关系集合
     *
     * @param mainId
     * @return
     */
    private List<FileConfig> getFileList(String mainId) {
        List<FileConfig> fileList = new ArrayList<>();
        RecordSet rs = new RecordSet();
        rs.executeQuery("select * from " + QualificationApplicationServiceImpl.FILE_DETAIL_TABLE_NAME + " where mainId = ?", mainId);

        while (rs.next()) {
            fileList.add(FileConfig.builder()
                    .fieldName(rs.getString("field_name"))
                    .fileId(rs.getString("file_id"))
                    .isFilled(rs.getString("file_type"))
                    .fixedValue(rs.getString("fixed_value"))
                    .attachments(rs.getString("attachments"))
                    .build());
        }
        return fileList;
    }

    /**
     * 解析配置文件爱你，构建ApplicationResource集合
     *
     * @param rootNode
     * @return
     */
    private List<ApplicationResource> getApplicationResourceList(JsonNode rootNode) {
        List<ApplicationResource> applicationResourceList = new ArrayList<>();
        JsonNode applicationResourceListNode = rootNode.at("/applicationResourceList");

        if (applicationResourceListNode != null && applicationResourceListNode.isArray()) {
            for (JsonNode jsonNode : applicationResourceListNode) {
                applicationResourceList.add(ApplicationResource.builder()
                        .id(jsonNode.at("/id").asText())
                        .aid(jsonNode.at("/aid").asText())
                        .fid(jsonNode.at("/fid").asText())
                        .rid(jsonNode.at("/rid").asText())
                        .createdTime(jsonNode.at("/createdTime").asText())
                        .isDelete(jsonNode.at("/isDelete").asText())
                        .build());
            }
        }
        return applicationResourceList;
    }


    /**
     * 解析配置文件爱你，构建ResourceInfo集合
     *
     * @param rootNode
     * @return
     */
    private List<ResourceInfo> getResourceInfoList(JsonNode rootNode) {
        List<ResourceInfo> resourceInfoList = new ArrayList<>();
        JsonNode resourceInfoListNode = rootNode.at("/resourceInfoList");

        if (resourceInfoListNode != null && resourceInfoListNode.isArray()) {
            for (JsonNode jsonNode : resourceInfoListNode) {
                resourceInfoList.add(ResourceInfo.builder()
                        .id(jsonNode.at("/id").asText())
                        .fileName(jsonNode.at("/fileName").asText())
                        .filePath(jsonNode.at("/filePath").asText())
                        .fileSuffix(jsonNode.at("/fileSuffix").asText())
                        .virtualPath(jsonNode.at("/virtualPath").asText())
                        .createdTime(jsonNode.at("/createdTime").asText())
                        .updatedTime(jsonNode.at("/updatedTime").asText())
                        .isDelete(jsonNode.at("/isDelete").asText())
                        .build());
            }
        }
        return resourceInfoList;
    }


    /**
     * 上传文件，生成imageFileId
     *
     * @param zipFile
     * @param header
     * @param fileName
     * @return
     */
    private int generateImageFileId(ZipFile zipFile, FileHeader header, String fileName) {
        try (InputStream is = zipFile.getInputStream(header)) {
            return ModeUtil.generateImageFileId(is, fileName);
        } catch (Exception e) {
            throw new CustomizeRunTimeException(e);
        }
    }


    /**
     * 获取主表的ID集合
     *
     * @param mainTableName
     * @return
     */
    private Set<Integer> getTableIdList(String mainTableName) {
        return insertTableMap.computeIfAbsent(mainTableName, k -> ConcurrentHashMap.newKeySet());

    }
}