package jnpf.storecertificatephoto.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jnpf.model.storecertificatephoto.po.StoreCertificatePhotoEntity;
import jnpf.model.warningnotice.enums.CertificateTypeEnum;
import jnpf.model.warningnotice.po.FtbParamEntity;
import jnpf.model.warningnotice.req.WarningNoticeSaveReq;
import jnpf.model.warningnotice.req.WarningNoticeTargetReq;
import jnpf.model.warningnotice.req.WarningNoticeUserConfigReq;
import jnpf.model.warningnotice.vo.WarningNoticeTargetVO;
import jnpf.model.warningnotice.vo.WarningNoticeUserConfigVO;
import jnpf.model.warningnotice.vo.WarningNoticeVO;
import jnpf.storecertificatephoto.helper.StoreCertificatePhotoHelper;
import jnpf.storecertificatephoto.mapper.BaseParamMapper;
import jnpf.storecertificatephoto.service.WarningNoticeService;
import jnpf.util.FtbUtil;
import jnpf.util.JsonUtil;
import jnpf.util.ServiceException;
import jnpf.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 预警通知服务实现
 */
@Service
public class WarningNoticeServiceImpl implements WarningNoticeService {

    private static final String CONFIG_KEY_PREFIX = "ftbWarningNotice_";
    /**
     * 预警配置类型
     */
    public static final String certificateWarnNoticeType = "certificateWarnNoticeType";
    private static final Long DEFAULT_SORT = 0L;

    @Autowired
    private BaseParamMapper baseParamMapper;
    @Autowired
    private PlatformTransactionManager transactionManager;
    @Autowired
    private StoreCertificatePhotoHelper storeCertificatePhotoHelper;

    /**
     * 保存预警通知配置
     *
     * @param req 保存请求参数
     * @return 预警通知配置
     */
    @Override
    public WarningNoticeVO save(WarningNoticeSaveReq req) {
        List<WarningNoticeVO> result = saveList(Collections.singletonList(req));
        ServiceException.isTrue(CollUtil.isNotEmpty(result), "保存预警配置失败");
        return result.get(0);
    }

    /**
     * 批量保存预警通知配置
     *
     * @param reqList 批量保存请求参数
     * @return 预警通知配置列表
     */
    @Override
    public List<WarningNoticeVO> saveList(List<WarningNoticeSaveReq> reqList) {
        ServiceException.isTrue(CollUtil.isNotEmpty(reqList), "保存参数不能为空");

        List<WarningNoticePreparedData> preparedList = prepareSaveDataList(reqList);
        validateBatchUniqueness(preparedList);
        BatchParamSplit split = splitById(preparedList);
        executeBatch(split);

        // 批量更新/插入后，按key回查最新数据，保证返回包含数据库最终ID
        List<String> keys = preparedList.stream()
                .map(item -> item.getEntity().getKey())
                .collect(Collectors.toList());
        List<WarningNoticeVO> result = queryByKeys(keys);
        ServiceException.isTrue(result.size() == keys.size(), "保存预警配置失败");
        return result;
    }

    /**
     * 根据证照类型查询预警通知配置
     *
     * @param type 证照类型
     * @return 预警通知配置
     */
    @Override
    public WarningNoticeVO queryByType(String type) {
        String key = buildConfigKey(type);
        FtbParamEntity entity = baseParamMapper.selectByKey(key);
        if (entity == null || StrUtil.isBlank(entity.getValue())) {
            return null;
        }

        WarningNoticeVO warningNoticeVO = buildWarningNoticeVO(entity);
        return normalizeWarningNoticeVO(warningNoticeVO);
    }

    private WarningNoticeVO buildWarningNoticeVO(FtbParamEntity entity) {
        WarningNoticeVO warningNoticeVO = JsonUtil.getJsonToBean(entity.getValue(), WarningNoticeVO.class);
        ServiceException.notNull(warningNoticeVO, "预警通知配置数据异常");
        warningNoticeVO.setKey(entity.getKey());
        String certificateType = buildCertificateTypeOrTemplateId(entity.getKey());
        Optional<CertificateTypeEnum> certificateTypeEnumOptional = CertificateTypeEnum.getByType(certificateType);
        ServiceException.isTrue(certificateTypeEnumOptional.isPresent(), "预警通知配置数据异常.证照类型异常");
        CertificateTypeEnum certificateTypeEnum = certificateTypeEnumOptional.get();
        warningNoticeVO.setType(certificateTypeEnum.getType());
        warningNoticeVO.setTypeOrTemplateId(certificateType);
        warningNoticeVO.setId(entity.getId());
        return warningNoticeVO;
    }

    @Override
    public List<WarningNoticeVO> queryAll() {
        List<FtbParamEntity> ftbParamEntities = baseParamMapper.selectList(new LambdaQueryWrapper<FtbParamEntity>().eq(FtbParamEntity::getType, certificateWarnNoticeType));
        if(CollectionUtil.isEmpty(ftbParamEntities)){
            return Collections.emptyList();
        }
        return ftbParamEntities.stream()
                .map(this::buildWarningNoticeVO)
                .collect(Collectors.toList());
    }

    /**
     * 构建基础参数实体
     *
     * @param saveData 预警通知配置
     * @param reqId 请求中的ID
     * @return 基础参数实体
     */
    private FtbParamEntity buildBaseParamEntity(WarningNoticeVO saveData, String reqId) {
        FtbParamEntity entity = new FtbParamEntity();
        entity.setId(StrUtil.isNotBlank(reqId) ? normalizeText(reqId) : FtbUtil.getId());
        entity.setKey(saveData.getKey());
        entity.setType(certificateWarnNoticeType);
        entity.setValue(JsonUtil.getObjectToString(saveData));
        entity.setSort(DEFAULT_SORT);
        return entity;
    }

    /**
     * 构建保存对象
     *
     * @param req 保存请求参数
     * @param certificateType 证照类型
     * @param key 参数键
     * @return 预警通知配置
     */
    private WarningNoticeVO buildSaveData(WarningNoticeSaveReq req, CertificateTypeEnum certificateType, String key) {
        WarningNoticeVO warningNoticeVO = new WarningNoticeVO();
        warningNoticeVO.setKey(key);
        warningNoticeVO.setType(certificateType.getType());
        warningNoticeVO.setExpiryReminderDays(req.getExpiryReminderDays());
        warningNoticeVO.setNoticeFrequencyDays(req.getNoticeFrequencyDays());

        List<WarningNoticeUserConfigVO> noticeConfigList = new ArrayList<>();
        for (WarningNoticeUserConfigReq configReq : req.getNoticeConfigList()) {
            WarningNoticeUserConfigVO configVO = new WarningNoticeUserConfigVO();
            configVO.setNoticeUserType(normalizeText(configReq.getNoticeUserType()));

            List<WarningNoticeTargetVO> noticeUserList = new ArrayList<>();
            for (WarningNoticeTargetReq targetReq : configReq.getNoticeUserList()) {
                WarningNoticeTargetVO targetVO = new WarningNoticeTargetVO();
                targetVO.setId(normalizeText(targetReq.getId()));
                targetVO.setName(normalizeText(targetReq.getName()));
                noticeUserList.add(targetVO);
            }
            configVO.setNoticeUserList(noticeUserList);
            noticeConfigList.add(configVO);
        }
        warningNoticeVO.setNoticeConfigList(noticeConfigList);
        return warningNoticeVO;
    }

    /**
     * 规范化返回对象
     *
     * @param warningNoticeVO 预警通知配置
     * @return 预警通知配置
     */
    private WarningNoticeVO normalizeWarningNoticeVO(WarningNoticeVO warningNoticeVO) {
        warningNoticeVO.setId(normalizeText(warningNoticeVO.getId()));
        warningNoticeVO.setKey(normalizeText(warningNoticeVO.getKey()));
        warningNoticeVO.setType(normalizeText(warningNoticeVO.getType()));
        if (warningNoticeVO.getNoticeConfigList() == null) {
            warningNoticeVO.setNoticeConfigList(new ArrayList<>());
            return warningNoticeVO;
        }

        for (WarningNoticeUserConfigVO configVO : warningNoticeVO.getNoticeConfigList()) {
            configVO.setNoticeUserType(normalizeText(configVO.getNoticeUserType()));
            if (configVO.getNoticeUserList() == null) {
                configVO.setNoticeUserList(new ArrayList<>());
                continue;
            }
            for (WarningNoticeTargetVO targetVO : configVO.getNoticeUserList()) {
                targetVO.setId(normalizeText(targetVO.getId()));
                targetVO.setName(normalizeText(targetVO.getName()));
            }
        }
        return warningNoticeVO;
    }

    /**
     * 校验通知人员配置
     *
     * @param noticeConfigList 通知人员配置列表
     */
    private void validateNoticeConfigList(List<WarningNoticeUserConfigReq> noticeConfigList) {
        ServiceException.isTrue(CollUtil.isNotEmpty(noticeConfigList), "临期通知人员不能为空");
        Set<String> noticeTypeSet = new HashSet<>();
        for (WarningNoticeUserConfigReq configReq : noticeConfigList) {
            ServiceException.notNull(configReq, "通知人员配置不能为空");
            String noticeUserType = normalizeText(configReq.getNoticeUserType());
            ServiceException.isTrue(StrUtil.isNotBlank(noticeUserType), "通知人员类型不能为空");
            ServiceException.isTrue(noticeTypeSet.add(noticeUserType), "通知人员类型不能重复");
            validateNoticeTargetList(configReq.getNoticeUserList());
        }
    }

    /**
     * 校验通知对象列表
     *
     * @param noticeUserList 通知对象列表
     */
    private void validateNoticeTargetList(List<WarningNoticeTargetReq> noticeUserList) {
        ServiceException.isTrue(CollUtil.isNotEmpty(noticeUserList), "通知对象不能为空");
        Set<String> targetIdSet = new HashSet<>();
        for (WarningNoticeTargetReq targetReq : noticeUserList) {
            ServiceException.notNull(targetReq, "通知对象不能为空");
            String id = normalizeText(targetReq.getId());
            String name = normalizeText(targetReq.getName());
            ServiceException.isTrue(StrUtil.isNotBlank(id), "通知对象ID不能为空");
            ServiceException.isTrue(targetIdSet.add(id), "同一通知人员类型下的通知对象不能重复");
        }
    }

    /**
     * 生成配置键
     *
     * @param certificateType 证照类型
     * @return 配置键
     */
    private String buildConfigKey(CertificateTypeEnum certificateType,String typeOrTemplateId) {
        if(CertificateTypeEnum.STORE_CUSTOM_CERTIFICATE.equals(certificateType)){
            return buildConfigKey(typeOrTemplateId);
        }
        return buildConfigKey(certificateType.getType());
    }

    /**
     * 生成配置键
     *
     * @param certificateType 证照类型
     * @return 配置键
     */
    private String buildConfigKey(String certificateType) {
        return CONFIG_KEY_PREFIX + certificateType;
    }

    /**
     * 根据配置键找出证照类型，如果是自定义证照，则是模板id
     *
     * @param key 配置键
     * @return 证照类型
     */
    private String buildCertificateTypeOrTemplateId(String key) {
        if(StringUtil.isBlank(key)){
            return null;
        }
        return key.substring(CONFIG_KEY_PREFIX.length());
    }

    /**
     * 规范化文本
     *
     * @param text 原始文本
     * @return 规范化后的文本
     */
    private String normalizeText(String text) {
        return StrUtil.trim(text);
    }

    /**
     * 批量执行保存。
     * 先按ID分流为更新/插入；若出现唯一键冲突，则根据type全量回查后重新分流并重试一次。
     *
     * @param split 批量分流数据
     */
    private void executeBatch(BatchParamSplit split) {
        try {
            executeBatchOnceInTransaction(split);
        } catch (Exception e) {
            if (!isDuplicateKeyException(e)) {
                throw e;
            }
            BatchParamSplit retrySplit = rebuildSplitByTypeFromDbInNewTransaction(split.getAllEntities());
            try {
                executeBatchOnceInTransaction(retrySplit);
            } catch (Exception ex) {
                if (!isDuplicateKeyException(ex)) {
                    throw ex;
                }
                throw new ServiceException("该证照类型的预警配置已存在");
            }
        }
    }

    /**
     * 单次执行批量更新+批量插入。
     *
     * @param split 分流结果
     */
    private void executeBatchOnce(BatchParamSplit split) {
        if (split == null || CollUtil.isEmpty(split.getAllEntities())) {
            return;
        }
        if (CollUtil.isNotEmpty(split.getUpdateEntities())) {
            baseParamMapper.batchUpdateById(split.getUpdateEntities());
        }
        if (CollUtil.isNotEmpty(split.getInsertEntities())) {
            baseParamMapper.batchInsertParam(split.getInsertEntities());
        }
    }

    /**
     * 在事务中执行一次批量写入。
     *
     * @param split 分流结果
     */
    private void executeBatchOnceInTransaction(BatchParamSplit split) {
        TransactionTemplate template = buildTransactionTemplate(TransactionDefinition.PROPAGATION_REQUIRED, false);
        template.execute(status -> {
            executeBatchOnce(split);
            return null;
        });
    }

    /**
     * 预处理批量请求：校验参数并构建VO/实体。
     *
     * @param reqList 请求列表
     * @return 预处理结果列表
     */
    private List<WarningNoticePreparedData> prepareSaveDataList(List<WarningNoticeSaveReq> reqList) {
        List<WarningNoticePreparedData> result = new ArrayList<>(reqList.size());
        Map<String, StoreCertificatePhotoEntity> stringStoreCertificatePhotoEntityMap = storeCertificatePhotoHelper.buildStoreCertificateById(reqList.stream()
                .map(WarningNoticeSaveReq::getTypeOrTemplateId)
                .filter(this::isStoreCertificateType)
                .collect(Collectors.toSet()),null);

        for (WarningNoticeSaveReq req : reqList) {
            ServiceException.notNull(req, "保存参数不能为空");
            String typeOrTemplateId = req.getTypeOrTemplateId();
            Optional<CertificateTypeEnum> certificateTypeEnumOptional= CertificateTypeEnum.getByType(typeOrTemplateId);
            ServiceException.isTrue(certificateTypeEnumOptional.isPresent(), "证照类型不能为空");
            CertificateTypeEnum certificateType = certificateTypeEnumOptional.get();
            Integer expiryReminderDays = req.getExpiryReminderDays();
            if (certificateType != CertificateTypeEnum.STORE_CUSTOM_CERTIFICATE) {
                ServiceException.notNull(expiryReminderDays, "临期提醒时间不能为空");
                ServiceException.isTrue(expiryReminderDays >= 0, "临期提醒时间必须大于等于0");
                ServiceException.isTrue(expiryReminderDays<=180, "临期提醒时间最大180");
            }else{
                StoreCertificatePhotoEntity storeCertificatePhotoEntity = stringStoreCertificatePhotoEntityMap.get(typeOrTemplateId);
                ServiceException.notNull(storeCertificatePhotoEntity, "自定义证照不存在["+typeOrTemplateId+"]");
                expiryReminderDays = storeCertificatePhotoEntity.getExpiryReminderDays();
            }
            ServiceException.notNull(req.getNoticeFrequencyDays(), "通知频率不能为空");
            if(Objects.nonNull(expiryReminderDays) && expiryReminderDays > 0){
                ServiceException.isTrue(req.getNoticeFrequencyDays() <= expiryReminderDays, "通知频率必须小于等于临期提醒");
            }
//            validateNoticeConfigList(req.getNoticeConfigList());

            String key = buildConfigKey(certificateType,typeOrTemplateId);
            WarningNoticeVO saveData = buildSaveData(req, certificateType, key);
            String reqId = normalizeText(req.getId());
            FtbParamEntity entity = buildBaseParamEntity(saveData, reqId);
            result.add(new WarningNoticePreparedData(typeOrTemplateId, reqId, entity));
        }
        return result;
    }

    private boolean isStoreCertificateType(String typeOrTemplateId) {
        Optional<CertificateTypeEnum> certificateTypeEnumOptional= CertificateTypeEnum.getByType(typeOrTemplateId);
        ServiceException.isTrue(certificateTypeEnumOptional.isPresent(), "证照类型不能为空");
        CertificateTypeEnum certificateType = certificateTypeEnumOptional.get();
        return CertificateTypeEnum.STORE_CUSTOM_CERTIFICATE.equals(certificateType);
    }

    /**
     * 按是否有ID进行分流：有ID走更新，无ID走插入。
     *
     * @param preparedList 预处理结果列表
     * @return 分流结果
     */
    private BatchParamSplit splitById(List<WarningNoticePreparedData> preparedList) {
        List<FtbParamEntity> updateEntities = new ArrayList<>();
        List<FtbParamEntity> insertEntities = new ArrayList<>();
        List<FtbParamEntity> allEntities = new ArrayList<>();
        for (WarningNoticePreparedData data : preparedList) {
            FtbParamEntity entity = data.getEntity();
            String reqId = data.getReqId();
            allEntities.add(entity);
            if (StrUtil.isNotBlank(reqId)) {
                updateEntities.add(entity);
            } else {
                insertEntities.add(entity);
            }
        }
        return new BatchParamSplit(updateEntities, insertEntities, allEntities);
    }

    /**
     * 批量参数唯一性校验。
     * 同一次请求中同一type只能出现一次，同一id只能出现一次。
     *
     * @param preparedList 预处理列表
     */
    private void validateBatchUniqueness(List<WarningNoticePreparedData> preparedList) {
        Set<String> typeSet = new HashSet<>();
        Set<String> reqIdSet = new HashSet<>();
        for (WarningNoticePreparedData data : preparedList) {
            String type = normalizeText(data.getType());
            ServiceException.isTrue(StrUtil.isNotBlank(type), "证照类型不能为空");
            ServiceException.isTrue(typeSet.add(type), "同一次请求中证照类型不能重复");

            String reqId = normalizeText(data.getReqId());
            if (StrUtil.isBlank(reqId)) {
                continue;
            }
            ServiceException.isTrue(reqIdSet.add(reqId), "同一次请求中ID不能重复");
        }
    }

    /**
     * duplicate key 后按 type 全量回查，重建更新/插入集合。
     *
     * @param entities 本次要保存的实体
     * @return 重建后的分流结果
     */
    private BatchParamSplit rebuildSplitByTypeFromDb(List<FtbParamEntity> entities) {
        if (CollUtil.isEmpty(entities)) {
            return new BatchParamSplit(Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
        }
        List<FtbParamEntity> dbList = baseParamMapper.selectList(
                new LambdaQueryWrapper<FtbParamEntity>().eq(FtbParamEntity::getType, certificateWarnNoticeType)
        );
        Map<String, FtbParamEntity> dbByKey = dbList.stream()
                .filter(Objects::nonNull)
                .filter(item -> StrUtil.isNotBlank(item.getKey()))
                .collect(Collectors.toMap(item -> StrUtil.trim(item.getKey()), item -> item, (a, b) -> a));

        List<FtbParamEntity> updateEntities = new ArrayList<>();
        List<FtbParamEntity> insertEntities = new ArrayList<>();
        List<FtbParamEntity> allEntities = new ArrayList<>();
        for (FtbParamEntity entity : entities) {
            if (entity == null || StrUtil.isBlank(entity.getKey())) {
                continue;
            }
            FtbParamEntity saveEntity = cloneParamEntity(entity);
            FtbParamEntity dbEntity = dbByKey.get(StrUtil.trim(saveEntity.getKey()));
            if (dbEntity != null && StrUtil.isNotBlank(dbEntity.getId())) {
                saveEntity.setId(StrUtil.trim(dbEntity.getId()));
                updateEntities.add(saveEntity);
            } else {
                if (StrUtil.isBlank(saveEntity.getId())) {
                    saveEntity.setId(FtbUtil.getId());
                }
                insertEntities.add(saveEntity);
            }
            allEntities.add(saveEntity);
        }
        return new BatchParamSplit(updateEntities, insertEntities, allEntities);
    }

    /**
     * 在新事务中按type回查并重建分流结果。
     *
     * @param entities 本次要保存的实体
     * @return 重建后的分流结果
     */
    private BatchParamSplit rebuildSplitByTypeFromDbInNewTransaction(List<FtbParamEntity> entities) {
        TransactionTemplate template = buildTransactionTemplate(TransactionDefinition.PROPAGATION_REQUIRES_NEW, true);
        BatchParamSplit split = template.execute(status -> rebuildSplitByTypeFromDb(entities));
        return split == null
                ? new BatchParamSplit(Collections.emptyList(), Collections.emptyList(), Collections.emptyList())
                : split;
    }

    /**
     * 构建事务模板。
     *
     * @param propagationBehavior 事务传播级别
     * @param readOnly 是否只读
     * @return 事务模板
     */
    private TransactionTemplate buildTransactionTemplate(int propagationBehavior, boolean readOnly) {
        TransactionTemplate template = new TransactionTemplate(transactionManager);
        template.setPropagationBehavior(propagationBehavior);
        template.setReadOnly(readOnly);
        return template;
    }

    /**
     * 按key列表查询预警配置，返回值与入参顺序一致。
     *
     * @param keys 配置key列表
     * @return 预警配置列表
     */
    private List<WarningNoticeVO> queryByKeys(List<String> keys) {
        if (CollUtil.isEmpty(keys)) {
            return Collections.emptyList();
        }
        List<FtbParamEntity> dbList = baseParamMapper.selectList(
                new LambdaQueryWrapper<FtbParamEntity>()
                        .eq(FtbParamEntity::getType, certificateWarnNoticeType)
                        .in(FtbParamEntity::getKey, keys)
        );
        Map<String, WarningNoticeVO> voByKey = dbList.stream()
                .filter(Objects::nonNull)
                .filter(item -> StrUtil.isNotBlank(item.getKey()))
                .collect(Collectors.toMap(
                        item -> StrUtil.trim(item.getKey()),
                        item -> normalizeWarningNoticeVO(buildWarningNoticeVO(item)),
                        (a, b) -> a
                ));

        List<WarningNoticeVO> result = new ArrayList<>(keys.size());
        for (String key : keys) {
            WarningNoticeVO vo = voByKey.get(StrUtil.trim(key));
            if (vo != null) {
                result.add(vo);
            }
        }
        return result;
    }

    /**
     * 复制参数实体，避免重试时修改原对象。
     *
     * @param source 原实体
     * @return 复制后的实体
     */
    private FtbParamEntity cloneParamEntity(FtbParamEntity source) {
        FtbParamEntity target = new FtbParamEntity();
        target.setId(normalizeText(source.getId()));
        target.setKey(normalizeText(source.getKey()));
        target.setType(normalizeText(source.getType()));
        target.setValue(source.getValue());
        target.setSort(source.getSort());
        return target;
    }

    /**
     * 判断异常链中是否包含唯一键冲突。
     *
     * @param throwable 异常
     * @return 是否唯一键冲突
     */
    private boolean isDuplicateKeyException(Throwable throwable) {
        Throwable current = throwable;
        while (current != null) {
            if (current instanceof DuplicateKeyException) {
                return true;
            }
            String message = current.getMessage();
            if (StrUtil.isNotBlank(message)
                    && StrUtil.containsIgnoreCase(message, "duplicate")
                    && StrUtil.containsIgnoreCase(message, "key")) {
                return true;
            }
            current = current.getCause();
        }
        return false;
    }

    /**
     * 预处理数据载体。
     */
    private static class WarningNoticePreparedData {
        private final String type;
        private final String reqId;
        private final FtbParamEntity entity;

        private WarningNoticePreparedData(String type, String reqId, FtbParamEntity entity) {
            this.type = type;
            this.reqId = reqId;
            this.entity = entity;
        }

        private String getType() {
            return type;
        }

        private String getReqId() {
            return reqId;
        }

        private FtbParamEntity getEntity() {
            return entity;
        }
    }

    /**
     * 批量更新/插入分流结果。
     */
    private static class BatchParamSplit {
        private final List<FtbParamEntity> updateEntities;
        private final List<FtbParamEntity> insertEntities;
        private final List<FtbParamEntity> allEntities;

        private BatchParamSplit(List<FtbParamEntity> updateEntities,
                                List<FtbParamEntity> insertEntities,
                                List<FtbParamEntity> allEntities) {
            this.updateEntities = updateEntities;
            this.insertEntities = insertEntities;
            this.allEntities = allEntities;
        }

        private List<FtbParamEntity> getUpdateEntities() {
            return updateEntities;
        }

        private List<FtbParamEntity> getInsertEntities() {
            return insertEntities;
        }

        private List<FtbParamEntity> getAllEntities() {
            return allEntities;
        }
    }
}
