package com.ruoyi.project.business.service.impl;

import static com.ruoyi.common.utils.jep.JEPUtils.AFTER_ANALYSIS_FORMULA;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.exception.ServiceErrorException;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.importExcel.excel.helper.BasicExcelHelper;
import com.ruoyi.common.importExcel.excel.helper.BasicTableInfoHelper;
import com.ruoyi.common.importExcel.excel.tempInfo.ParaValidationInfoHelper;
import com.ruoyi.common.importExcel.utils.ExcelUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ValidateUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.jep.JEPUtils;
import com.ruoyi.project.business.domain.TpParaLibrary;
import com.ruoyi.project.business.domain.TpParaValidation;
import com.ruoyi.project.business.domain.TpParaValidationElevator;
import com.ruoyi.project.business.domain.TpParabar;
import com.ruoyi.project.business.domain.bo.validation.ComputeQueryBO;
import com.ruoyi.project.business.domain.bo.validation.ElevatorQueryBO;
import com.ruoyi.project.business.domain.vo.parabar.RelatedModelVO;
import com.ruoyi.project.business.domain.vo.validataion.ComputeResultVO;
import com.ruoyi.project.business.domain.vo.validataion.ParamCheckResultVO;
import com.ruoyi.project.business.dto.TpParaValidationDto;
import com.ruoyi.project.business.dto.TpParaValidationElevatorDto;
import com.ruoyi.project.business.enums.CalculateResultEnum;
import com.ruoyi.project.business.enums.DelFlagEnum;
import com.ruoyi.project.business.enums.JEPFuncEnum;
import com.ruoyi.project.business.enums.JEPLogicEnum;
import com.ruoyi.project.business.enums.JEPSplitEnum;
import com.ruoyi.project.business.enums.OperationFlagEnum;
import com.ruoyi.project.business.enums.ParamTypeEnum;
import com.ruoyi.project.business.mapper.TpParaValidationMapper;
import com.ruoyi.project.business.service.ITpParaLibraryService;
import com.ruoyi.project.business.service.ITpParaValidationElevatorService;
import com.ruoyi.project.business.service.ITpParaValidationService;
import com.ruoyi.project.business.service.ITpParabarService;
import com.ruoyi.project.business.service.quotation.ITqSpecificationService;
import com.ruoyi.project.system.domain.SysDictData;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.service.ISysUserService;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 校验规则配置Service业务层处理
 *
 * @author ruoyi
 * @date 2024-04-29
 */
@Service
@Slf4j
public class TpParaValidationServiceImpl extends ServiceImpl<TpParaValidationMapper, TpParaValidation> implements
    ITpParaValidationService {

    public static final String CALCULATE_VALUE_TRUE = "1.0";

    @Resource
    private TpParaValidationMapper tpParaValidationMapper;

    @Resource
    private ITpParaValidationElevatorService iTpParaValidationElevatorService;

    @Resource
    private ISysUserService iSysUserService;

    @Resource
    private ITpParaLibraryService tpParaLibraryService;

    @Resource
    private ITpParabarService tpParabarService;

    @Resource
    private ITqSpecificationService iTqSpecificationService;

    /**
     * 查询校验规则配置
     *
     * @param id 校验规则配置主键
     * @return 校验规则配置
     */
    @Override
    public TpParaValidation selectTpParaValidationById(Long id) {
        return tpParaValidationMapper.selectTpParaValidationById(id);
    }

    /**
     * 查询校验规则配置列表
     *
     * @param tpParaValidation 校验规则配置
     * @return 校验规则配置
     */
    @Override
    public List<TpParaValidation> selectTpParaValidationList(TpParaValidation tpParaValidation) {
        return tpParaValidationMapper.selectTpParaValidationList(tpParaValidation);
    }

    /**
     * 新增校验规则配置
     *
     * @param tpParaValidation 校验规则配置
     * @return 结果
     */
    @Override
    public int insertTpParaValidation(TpParaValidation tpParaValidation) {
        tpParaValidation.setCreateTime(DateUtils.getNowDate());
        return tpParaValidationMapper.insertTpParaValidation(tpParaValidation);
    }

    /**
     * 修改校验规则配置
     *
     * @param tpParaValidation 校验规则配置
     * @return 结果
     */
    @Override
    public int updateTpParaValidation(TpParaValidation tpParaValidation) {
        tpParaValidation.setUpdateTime(DateUtils.getNowDate());
        return tpParaValidationMapper.updateTpParaValidation(tpParaValidation);
    }

    /**
     * 批量删除校验规则配置
     *
     * @param ids 需要删除的校验规则配置主键
     * @return 结果
     */
    @Override
    public int deleteTpParaValidationByIds(Long[] ids) {
        return tpParaValidationMapper.deleteTpParaValidationByIds(ids);
    }

    /**
     * 删除校验规则配置信息
     *
     * @param id 校验规则配置主键
     * @return 结果
     */
    @Override
    public int deleteTpParaValidationById(Long id) {
        return tpParaValidationMapper.deleteTpParaValidationById(id);
    }

    @Override
    public List<TpParaValidationDto> getTableList(TpParaValidationDto param) {
        List<TpParaValidationDto> dataList = tpParaValidationMapper.getTableList(param);
        if (dataList != null && !dataList.isEmpty()) {
            //取出所有的id
            List<Long> ids = dataList.stream().map(TpParaValidationDto::getId).collect(Collectors.toList());
            //取出所有的 创建人id，更新人id
            List<Long> createUserIds = dataList.stream().map(item -> Long.valueOf(item.getCreateBy()))
                .collect(Collectors.toList());
            List<Long> updateUserIds = dataList.stream().filter(item -> Objects.nonNull(item.getUpdateBy()))
                .map(item -> Long.valueOf(item.getUpdateBy())).collect(Collectors.toList());
            if (!updateUserIds.isEmpty()) {
                createUserIds.addAll(updateUserIds);
            }
            List<SysUser> userList = iSysUserService.listByIds(createUserIds);

            Map<Long, String> userMap = userList.stream()
                .collect(Collectors.toMap(SysUser::getUserId, SysUser::getNickName));
            //回显nickName
            if (!userMap.isEmpty()) {
                dataList.forEach(item -> {
                    if (isNotBlank(item.getCreateBy())) {
                        item.setCreateByName(userMap.get(Long.valueOf(item.getCreateBy())));
                    }
                    if (isNotBlank(item.getUpdateBy())) {
                        item.setUpdateByName(userMap.get(Long.valueOf(item.getUpdateBy())));
                    }
                });
            }

            List<TpParaValidationElevator> relationEnters = iTpParaValidationElevatorService
                .list(Wrappers.<TpParaValidationElevator>lambdaQuery()
                    .in(TpParaValidationElevator::getParaValidationId, ids)
                    .eq(TpParaValidationElevator::getDelFlag, DelFlagEnum.NORMAL.getValue()));
            List<Long> relatedElevatorIds = relationEnters.stream().map(TpParaValidationElevator::getElevatorModelId).collect(Collectors.toList());
            List<RelatedModelVO> relatedModelVOList = Lists.newArrayList();
            if (CollectionUtils.isNotEmpty(relatedElevatorIds)) {
                TpParabar tpParabar = new TpParabar();
                tpParabar.setShowType(false);
                tpParabar.setRelatedType("3");
                relatedModelVOList = tpParabarService.getRelatedModelList(tpParabar);
            }
            Map<Long, String> modelNameMap = relatedModelVOList.stream().collect(Collectors.toMap(RelatedModelVO::getParabarId, RelatedModelVO::getRelatedModel));

            Map<Long, List<TpParaValidationElevator>> countMap = relationEnters.stream()
                .collect(Collectors.groupingBy(TpParaValidationElevator::getParaValidationId));
            //设置 关联数量
            if (!countMap.isEmpty()) {
                dataList.forEach(item -> {
                    if (countMap.containsKey(item.getId())) {
                        item.setRelatedModel(countMap.get(item.getId()).stream().map(it -> modelNameMap.get(it.getElevatorModelId())).collect(Collectors.joining(";")));
                    }
                });
            }

            //回显公式
            // @Date 2024/6/7 15:49 @Author jubs 😀 @description:业务变更，已经有原始的不需要转换的公式
         /*   List<String> paramsList = new ArrayList<>();

            for (TpParaValidationDto data : dataList) {
                paramsList.addAll(JEPUtils.getParam(data.getConditionFormula()));
            }
            paramsList = paramsList.stream().distinct().sorted(
                Comparator.comparingInt(String::length)
            ).collect(Collectors.toList());
            //查询所有的 参数

            if(!paramsList.isEmpty()){
                List<TpParaLibrary> libraries = iTpParaLibraryService.list(
                        Wrappers.<TpParaLibrary>lambdaQuery()
                                .in(TpParaLibrary::getParaCode, paramsList)
                );
                Map<String, String> codeToNameMap = new HashMap<>();
                if (!libraries.isEmpty()) {
                    codeToNameMap = libraries.stream().collect(Collectors
                            .toMap(TpParaLibrary::getParaCode, TpParaLibrary::getParaName));
                }

                for (TpParaValidationDto data : dataList) {
                    //替换逻辑判断符号 && ||
                    data.setConditionFormula(
                            data.getConditionFormula().replace(JEPLogicEnum.OR.getLogicValue(), JEPLogicEnum.OR.getLogicKey()));
                    data.setConditionFormula(data.getConditionFormula()
                            .replace(JEPLogicEnum.AND.getLogicValue(), JEPLogicEnum.AND.getLogicKey()));
                    //替换 方法
                    List<String> funcList = JEPUtils.getFuncShort(data.getConditionFormula());
                    for (String func : funcList) {
                        String formula = data.getConditionFormula();
                        formula = formula.replace(JEPSplitEnum.FUNC_SPLIT_FLAG.getFuncKey(), "");
                        func = func.replace(JEPSplitEnum.FUNC_SPLIT_FLAG.getFuncKey(), "");
                        JEPFuncEnum jEPFuncEnum = JEPFuncEnum.fromByKey(func);
                        formula = formula.replace(func, jEPFuncEnum.getFuncValue());
                        data.setConditionFormula(formula);
                    }
                    //替换 参数
                    String formula = data.getConditionFormula();
                    List<String> params = JEPUtils.getParam(formula);
                    for (String s : params) {
                        s = s.replace(JEPSplitEnum.PARAM_SPLIT_FLAG.getFuncKey(), "");
                        if (codeToNameMap.containsKey(s)) {
                            formula = formula.replace(s, codeToNameMap.get(s))
                                    .replace(JEPSplitEnum.PARAM_SPLIT_FLAG.getFuncKey(), "");
                            data.setConditionFormula(formula);
                        }
                    }
                }
            }*/

        }

        return dataList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int saveOrUpdate(TpParaValidationDto param) {
        Integer operationFlag = param.getOperationFlag();
        Date date = DateUtils.getNowDate();
        //校验唯一性
        boolean uniqueFlag = checkUnique(param.getCaseName(), param.getId(), operationFlag);
        if (!uniqueFlag) {
            // 规则名称唯一
            throw new ServiceErrorException(MessageUtils.message("validation.noQuine"));
        }
        if (param.getRelationEnters() == null || param.getRelationEnters().isEmpty()) {
            //请选择 关联梯型
            throw new ServiceErrorException(MessageUtils.message("validation.pleaseSelectRelation"));
        }
        List<TpParaValidationElevator> relationEnters = param.getRelationEnters().stream().map(item -> {
            TpParaValidationElevator relationEnter = new TpParaValidationElevator();
            BeanUtils.copyBeanProp(relationEnter, item);
            return relationEnter;
        }).collect(Collectors.toList());

        //新增
        if (OperationFlagEnum.ADD.getFlag().equals(operationFlag)) {
            TpParaValidation tpParaValidation = new TpParaValidation();
            BeanUtils.copyBeanProp(tpParaValidation, param);
            tpParaValidation.setCreateBy(SecurityUtils.getStrUserId());
            tpParaValidation.setCreateTime(date);
            this.save(tpParaValidation);
            //relationEnters 来源是 tp_elevator_model
            relationEnters.forEach(item -> {
                item.setCreateBy(SecurityUtils.getStrUserId());
                item.setCreateTime(date);
                item.setParaValidationId(tpParaValidation.getId());
            });
            iTpParaValidationElevatorService.saveBatch(relationEnters);
        } else if (OperationFlagEnum.EDIT.getFlag().equals(operationFlag)) {
            //编辑
            TpParaValidation sqlData = getById(param.getId());
            if (sqlData == null) {
                //数据已被删除
                throw new ServiceErrorException(MessageUtils.message("common.dataDeleted"));
            }
            if (!ValidateUtils.allowUpdate(sqlData.getUpdateTime(), param.getUpdateTime())) {
                throw new ServiceErrorException(MessageUtils.message("common.dataUpdated"));
            }
            if (param.getDeleteRelationEnterIds() != null && param.getDeleteRelationEnterIds().size() > 0) {
                List<TpParaValidationElevator> deleteRelationEnters = iTpParaValidationElevatorService.list(Wrappers
                    .<TpParaValidationElevator>lambdaQuery()
                    .in(TpParaValidationElevator::getId, param.getDeleteRelationEnterIds())
                    .eq(TpParaValidationElevator::getDelFlag, DelFlagEnum.NORMAL.getValue()));
                if (deleteRelationEnters == null || deleteRelationEnters.size() == 0
                    || deleteRelationEnters.size() != param.getDeleteRelationEnterIds().size()) {
                    throw new ServiceErrorException(MessageUtils.message("common.relationDeleted"));
                }
                deleteRelationEnters.forEach(item -> {
                    item.setUpdateBy(SecurityUtils.getStrUserId());
                    item.setUpdateTime(date);
                    item.setDelFlag(DelFlagEnum.DELETED.getValue());
                });
                iTpParaValidationElevatorService.updateBatchById(deleteRelationEnters);
            }
            List<TpParaValidationElevator> addRealtionEnters = relationEnters.stream()
                .filter(item -> OperationFlagEnum.ADD.getFlag().equals(item.getOperationFlag()))
                .collect(Collectors.toList());
            if (!addRealtionEnters.isEmpty()) {
                addRealtionEnters.forEach(item -> {
                    item.setCreateTime(date);
                    item.setCreateBy(SecurityUtils.getStrUserId());
                    item.setParaValidationId(param.getId());
                });
                iTpParaValidationElevatorService.saveBatch(addRealtionEnters);
            }
            TpParaValidation tpParaValidation = new TpParaValidation();
            BeanUtils.copyBeanProp(tpParaValidation, param);
            tpParaValidation.setUpdateTime(date);
            tpParaValidation.setUpdateBy(SecurityUtils.getStrUserId());
            this.updateById(tpParaValidation);
        } else {
            log.info("公式规则配置，操作符错误，operationFlag={}", operationFlag);
        }
        return 0;
    }

    @Override
    public TpParaValidationDto getInfoById(Long id) {
        TpParaValidationDto basicInfoDto = new TpParaValidationDto();
        TpParaValidation basicInfo = getById(id);
        if (Objects.isNull(basicInfo)) {
            //数据已被删除
            throw new ServiceErrorException(MessageUtils.message("common.dataDeleted"));
        }
        BeanUtils.copyBeanProp(basicInfoDto, basicInfo);

        List<TpParaValidationElevatorDto> relationEnters = iTpParaValidationElevatorService.initData(
            basicInfoDto.getId());
        basicInfoDto.setRelationEnters(relationEnters);
        Map<String, Object> result = JEPUtils.analysisFormula(basicInfo.getConditionFormula());
        basicInfoDto.setFormulaValueStr(result.get(AFTER_ANALYSIS_FORMULA).toString());
        return basicInfoDto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteById(Long id, Date updateTime) {
        TpParaValidation sqlData = getById(id);
        if (sqlData == null||DelFlagEnum.DELETED.getValue().equals(sqlData.getDelFlag())) {
            //数据已被删除
            throw new ServiceErrorException(MessageUtils.message("common.dataDeleted"));
        }
        if (!ValidateUtils.allowUpdate(sqlData.getUpdateTime(), updateTime)) {
            throw new ServiceErrorException(MessageUtils.message("common.dataUpdated"));
        }


        Date date = new Date();
        //step 1: 删除关联表
        List<TpParaValidationElevator> relationEnters = iTpParaValidationElevatorService.list(
            Wrappers.<TpParaValidationElevator>lambdaQuery()
                .in(TpParaValidationElevator::getParaValidationId, id)
                .eq(TpParaValidationElevator::getDelFlag, DelFlagEnum.NORMAL.getValue())
        );
        // @Date 2024/6/27 13:04 @Author jubs 😀 @description:不需要限制
        /*if(CollectionUtils.isNotEmpty(relationEnters)){
            List<Long> elevatorIds=relationEnters.stream().map(TpParaValidationElevator::getElevatorModelId).collect(Collectors.toList());
            // @Date 2024/6/21 11:11 @Author jubs 😀 @description:追加限制 如果报价 引用了规则，则不允许删除
            List<TqSpecification> relaTedTqSpecification = iTqSpecificationService.list(
                    Wrappers.<TqSpecification>lambdaQuery()
                            .in(TqSpecification::getElevatorModelId, elevatorIds)
                            .eq(TqSpecification::getDelFlag, DelFlagEnum.NORMAL.getValue()));
            if(CollectionUtils.isNotEmpty(relaTedTqSpecification)){
                    throw  new ServiceErrorException(MessageUtils.message("validation.validateDeleteError"));
            }
        }*/
        relationEnters.forEach(item -> {
            item.setUpdateTime(date);
            item.setUpdateBy(SecurityUtils.getStrUserId());
            item.setDelFlag(DelFlagEnum.DELETED.getValue());
        });
        iTpParaValidationElevatorService.updateBatchById(relationEnters);
        sqlData.setUpdateBy(SecurityUtils.getStrUserId());
        sqlData.setUpdateTime(date);
        sqlData.setDelFlag(DelFlagEnum.DELETED.getValue());
        updateById(sqlData);
        return 1;
    }

    @Override
    public int changeStatus(TpParaValidationDto param) {
        TpParaValidation sqlData = getById(param.getId());
        if (sqlData == null) {
            //数据已被删除
            throw new ServiceErrorException(MessageUtils.message("common.dataDeleted"));
        }
        if (!ValidateUtils.allowUpdate(sqlData.getUpdateTime(), param.getUpdateTime())) {
            throw new ServiceErrorException(MessageUtils.message("common.dataUpdated"));
        }
        sqlData.setStatus(param.getStatus());
        sqlData.setUpdateBy(SecurityUtils.getStrUserId());
        sqlData.setUpdateTime(new Date());
        updateById(sqlData);
        return 0;
    }

    boolean checkUnique(String caseName, Long id, Integer operationFlag) {
        List<TpParaValidation> list = list(Wrappers.<TpParaValidation>lambdaQuery()
            .eq(TpParaValidation::getCaseName, caseName)
            .eq(TpParaValidation::getDelFlag, DelFlagEnum.NORMAL.getValue()));

        if (OperationFlagEnum.ADD.getFlag().equals(operationFlag)) {
            return list == null || list.size() == 0;
        } else if (OperationFlagEnum.EDIT.getFlag().equals(operationFlag)) {

            if (list != null && list.size() > 0) {
                List<Long> ids = list.stream().map(TpParaValidation::getId).filter(itemId -> !itemId.equals(id))
                    .collect(Collectors.toList());
                return ids.size() == 0;
            }
        }
        return true;
    }

    @Override
    public List<ParamCheckResultVO> checkElevatorParam(ElevatorQueryBO queryBO) {
        List<ParamCheckResultVO> resultVOList = new ArrayList<>();
        List<TpParaValidation> tpParaValidationList = this.baseMapper.listByElevatorModelId(
            queryBO.getElevatorModelId(), queryBO.getQuotationFlag());
        List<String> paramCodeList = new ArrayList<>();
        Map<String, Object> paramMap = new HashMap<>();
        if (CollUtil.isNotEmpty(queryBO.getParamList())) {
            queryBO.getParamList().forEach(item -> {
                if (!item.getParamType().equals(ParamTypeEnum.BAR.getCode())) {
                    paramMap.put(JEPSplitEnum.PARAM_SPLIT_FLAG.getFuncKey() + item.getParaCode()
                            + JEPSplitEnum.PARAM_SPLIT_FLAG.getFuncKey(),
                        item.getParaValue());
                    paramCodeList.add(item.getParaCode());
                }
            });
        }
        Map<String, String> paramCodeInputTypeMap = new HashMap<>();
        if (CollUtil.isNotEmpty(paramCodeList)) {
            List<TpParaLibrary> tpParaLibraryList = tpParaLibraryService.list(Wrappers.<TpParaLibrary>lambdaQuery()
                .in(TpParaLibrary::getParaCode, paramCodeList));

            paramCodeInputTypeMap = tpParaLibraryList.stream()
                .collect(Collectors.toMap(a -> JEPSplitEnum.PARAM_SPLIT_FLAG.getFuncKey() + a.getParaCode()
                    + JEPSplitEnum.PARAM_SPLIT_FLAG.getFuncKey(), TpParaLibrary::getInputType, (a, b) -> a));
        }
        for (TpParaValidation tpParaValidation : tpParaValidationList) {
            Map<String, Object> calculate = JEPUtils.calculate(tpParaValidation.getConditionFormulaAnalysis(),
                paramMap, paramCodeInputTypeMap, true);
            String result = String.valueOf(calculate.get(JEPUtils.CALCULATE_RESULT));
            String calculateValue = String.valueOf(calculate.get(JEPUtils.CALCULATE_VALUE));
            // 计算结果NG || 计算值不等于1.0 为校验失败
            if (CalculateResultEnum.NG.getValue().equals(result) || !calculateValue.equals(CALCULATE_VALUE_TRUE)) {
                ParamCheckResultVO convert = ParamCheckResultVO.convert(tpParaValidation);
                convert.setResult(result);
                convert.setCalculateValue(calculateValue);
                resultVOList.add(convert);
            }
            log.info("[{}] 计算结果  [{}]", tpParaValidation.getCaseName(), result);
        }
        return resultVOList;
    }

    @Override
    public ComputeResultVO computeElevatorParam(ComputeQueryBO queryBO) {
        ComputeResultVO resultVO = new ComputeResultVO();
        if (isBlank(queryBO.getFormula())) {
            return resultVO;
        }
        Map<String, Object> paramMap = new HashMap<>();
        Map<String, String> paramCodeInputTypeMap = new HashMap<>();
        if (CollUtil.isNotEmpty(queryBO.getParamList())) {
            queryBO.getParamList().forEach(item -> {
                if (!item.getParamType().equals(ParamTypeEnum.BAR.getCode())) {
                    paramMap.put(JEPSplitEnum.PARAM_SPLIT_FLAG.getFuncKey() + item.getParaCode()
                            + JEPSplitEnum.PARAM_SPLIT_FLAG.getFuncKey(),
                        item.getParaValue());

                    paramCodeInputTypeMap.put(JEPSplitEnum.PARAM_SPLIT_FLAG.getFuncKey() + item.getParaCode()
                        + JEPSplitEnum.PARAM_SPLIT_FLAG.getFuncKey(), item.getInputType());
                }
            });
        }

        Map<String, Object> calculate = JEPUtils.calculate(queryBO.getFormula(), paramMap, paramCodeInputTypeMap, true);
        String result = String.valueOf(calculate.get(JEPUtils.CALCULATE_RESULT));
        String calculateValue = String.valueOf(calculate.get(JEPUtils.OBJECT_CALCULATE_VALUE));
        if (CalculateResultEnum.NG.getValue().equals(result)) {
            return resultVO;
        }
        if (isNotBlank(calculateValue)) {
            resultVO.setCalculateValue(calculateValue);
            resultVO.setResult(true);
        }
        return resultVO;
    }

    @Override
    public List<? extends List<? extends BasicExcelHelper>> getParaValidationList() {
        List<List<? extends BasicExcelHelper>> result = com.google.common.collect.Lists.newArrayList();
        // 1. 获取所有校验规则
        List<TpParaValidationDto> tpParaValidationList = getTableList(new TpParaValidationDto());
        if (CollectionUtils.isEmpty(tpParaValidationList)){
            return result;
        }
        Map<String, String> yesNoMap = DictUtils.getDictCache("yes_no_tinyint").stream()
                .collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        Map<String, String> statusMap = DictUtils.getDictCache("status_switch").stream()
                .collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));


        result.add(tpParaValidationList.stream().map(item -> {
            ParaValidationInfoHelper excelHelper = new ParaValidationInfoHelper();
            BeanUtils.copyProperties(item, excelHelper);
            excelHelper.setStatus(statusMap.get(item.getStatus()));
            excelHelper.setQuotationFlag(yesNoMap.get(item.getQuotationFlag()));
            excelHelper.setCivilFlag(yesNoMap.get(item.getCivilFlag()));
            return excelHelper;
        }).collect(Collectors.toList()));

        return result;
    }

    @Override
    public ExcelUtils.UploadResult<ParaValidationInfoHelper> checkParaValidation(BasicTableInfoHelper tableInfoHelper, List<ParaValidationInfoHelper> list) {

        TpParabar paraBarParam = new TpParabar();
        paraBarParam.setShowType(Boolean.FALSE);
        paraBarParam.setRelatedType(null);
        List<RelatedModelVO> relatedModelVOList = tpParabarService.getRelatedModelList(paraBarParam);
        Map<String, Long> elevatorModelNameMap = relatedModelVOList.stream().collect(Collectors.toMap(RelatedModelVO::getRelatedModel, RelatedModelVO::getParabarId));

        return ExcelUtils.checkData(list, it -> {
            List<String> businessErrors = new ArrayList();

            if (Objects.nonNull(it.getRelatedModel())){
                String invalidNames = Arrays.stream(it.getRelatedModel().split(";"))
                        .filter(modelName -> Objects.isNull(elevatorModelNameMap.get(modelName)))
                        .collect(Collectors.joining(";"));
                if (StringUtils.isNotBlank(invalidNames)) {
                    businessErrors.add("关联梯型不存在：" + invalidNames);
                }
            }

            if (isNotBlank(it.getStatus()) && isBlank(DictUtils.getDictValue("status_switch", it.getStatus()))){
                businessErrors.add("状态不存在：" + it.getStatus());
            }

            return businessErrors;
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<String> insertParaValidation(BasicTableInfoHelper basicTableInfoHelper, List<ParaValidationInfoHelper> dataList) {
        if (CollectionUtils.isEmpty(dataList)){
            throw new ServiceException("导入数据不能为空");
        }

        TpParaLibrary library = new TpParaLibrary();
        List<TpParaLibrary> libraryList = tpParaLibraryService.selectTpParaLibraryList(library).stream()
                .sorted(Comparator.comparing(item -> -item.getParaName().length())).collect(Collectors.toList());
        Map<String, String> yesNoMap = DictUtils.getDictCache("yes_no_tinyint").stream()
                .collect(Collectors.toMap(SysDictData::getDictLabel, SysDictData::getDictValue));
        Map<String, String> statusMap = DictUtils.getDictCache("status_switch").stream()
                .collect(Collectors.toMap(SysDictData::getDictLabel, SysDictData::getDictValue));

        // 用于公式替换
        Function<String, String> replaceNames = formula -> {
            if (isBlank(formula)){
                return "";
            }

            // 1. 替换逻辑操作符
            for (JEPLogicEnum item : JEPLogicEnum.values()) {
                formula = formula.replaceAll(StringUtils.initLogicRegpx(item.getLogicKey()), item.getLogicValue());
            }

            // 2. 替换函数操作符
            for (JEPFuncEnum item : JEPFuncEnum.values()) {
                formula = formula.replaceAll(StringUtils.initFuncRegpx(item.getFuncValue()), Matcher.quoteReplacement("$@$" + item.getFuncKey() + "$@$"));
            }

            // 3. 替换变量名
            for (TpParaLibrary item: libraryList){
                formula = formula.replaceAll(StringUtils.initRegpx(item.getParaName()), Matcher.quoteReplacement("$_$" + item.getParaCode() + "$_$"));
            }

            return formula;
        };

        // 1. 区分数据是规则校验还是关联梯型信息
        List<TpParaValidation> validationList = new ArrayList<>();
        List<TpParaValidationElevator> relationList = new ArrayList<>();

        TpParabar paraBarParam = new TpParabar();
        paraBarParam.setShowType(Boolean.FALSE);
        paraBarParam.setRelatedType(null);
        List<RelatedModelVO> relatedModelVOList = tpParabarService.getRelatedModelList(paraBarParam);
        Map<String, Long> elevatorModelNameMap = relatedModelVOList.stream().collect(Collectors.toMap(RelatedModelVO::getRelatedModel, RelatedModelVO::getParabarId));


        for (ParaValidationInfoHelper item: dataList) {
            TpParaValidation validation = new TpParaValidation();
            BeanUtils.copyProperties(item, validation);
            validation.setStatus(statusMap.get(item.getStatus()));
            validation.setQuotationFlag(yesNoMap.get(item.getQuotationFlag()));
            validation.setCivilFlag(yesNoMap.get(item.getCivilFlag()));
            validation.setConditionFormulaAnalysis(replaceNames.apply(item.getConditionFormula()));
            validationList.add(validation);

            relationList.addAll(Arrays.stream(item.getRelatedModel().split(";")).map(modelName -> {
                TpParaValidationElevator relation = new TpParaValidationElevator();
                relation.setCaseName(item.getCaseName());
                relation.setElevatorModelId(elevatorModelNameMap.get(modelName));
                return relation;
            }).collect(Collectors.toList()));
        }

        // 2. 更新数据
        baseMapper.clearAll();
        if (CollectionUtils.isNotEmpty(validationList)){
            saveBatch(validationList);
        }
        Map<String, Long> idMap = validationList.stream().collect(Collectors.toMap(TpParaValidation::getCaseName, TpParaValidation::getId));
        relationList.forEach(relation -> relation.setParaValidationId(idMap.get(relation.getCaseName())));
        iTpParaValidationElevatorService.clearAll();
        if (CollectionUtils.isNotEmpty(relationList)){
            iTpParaValidationElevatorService.saveBatch(relationList);
        }

        return new ArrayList<>();
    }
}
