package com.ho.business.service.impl;

import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Expression;
import com.ho.business.constant.DeviceTypeConstant;
import com.ho.business.entity.*;
import com.ho.business.mapper.*;
import com.ho.business.service.DeviceService;
import com.ho.business.service.DynamicConfigService;
import com.ho.business.service.EarningsCalculateService;
import com.ho.business.service.OutApiService;
import com.ho.business.vo.DeviceTransfer;
import com.ho.business.vo.req.DeviceReqVO;
import com.ho.business.vo.req.MonitorQuery;
import com.ho.business.vo.req.carbin.EarningsCalculateReq;
import com.ho.business.vo.req.dynamicConfig.*;
import com.ho.business.vo.resp.DeviceRespVO;
import com.ho.business.vo.resp.dynamicConfig.*;
import com.ho.common.tools.constant.CommonConstant;
import com.ho.common.tools.service.RedisService;
import com.ho.common.tools.util.TranslateUtils;
import com.ho.datacollect.api.constant.DataCollectConstant;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
public class DynamicConfigServiceImpl implements DynamicConfigService {

    @Autowired
    DynamicConfigMapper dynamicConfigMapper;

    @Autowired
    CurveConfigMapper curveConfigMapper;

    @Autowired
    CurveConfigRelationMapper relationMapper;

    @Autowired
    PointConfigMapper pointConfigMapper;

    @Autowired
    PointConfigRelationMapper pointRelationMapper;

    @Autowired
    PointPolysemyConfigMapper polysemyMapper;

    @Autowired
    PointDisassembleConfigMapper disassembleMapper;

    @Autowired
    EarningsCalculateService earningsCalculateService;

    @Autowired
    RedisService redisService;

    @Autowired
    DeviceService deviceService;

    @Autowired
    OutApiService outApiService;

    @Autowired
    DynamicConfigTitleMapper configTitleMapper;

    @Autowired
    TranslateNameMapper translateNameMapper;

    @Override
    public int insertList(List<DynamicConfig> list) {
        List<DynamicConfig> insertList = list.stream().filter(i -> i.getId() == null).collect(Collectors.toList());
        List<DynamicConfig> updateList = list.stream().filter(i -> i.getId() != null).collect(Collectors.toList());
        int result = CommonConstant.ZERO;
        if(!insertList.isEmpty()){
            result = dynamicConfigMapper.insertList(insertList);
            log.info("配置信息插入结果{}",result);
        }
        if(!updateList.isEmpty()){
            result = dynamicConfigMapper.updateList(updateList);
            log.info("配置信息更新结果{}",result);
        }
        return result;
    }

    @Override
    public int updateList(List<DynamicConfig> list) {
        int result = dynamicConfigMapper.updateList(list);
        return result;
    }

    @Override
    public List<DynamicConfig> selectByParam(DynamicConfigQuery vo) {
        DynamicConfig config = new DynamicConfig();
        BeanUtils.copyProperties(vo,config);
        List<DynamicConfig> dynamicConfigs = dynamicConfigMapper.selectByParam(config);
        return dynamicConfigs;
    }

    @Override
    public int deleteByIds(List<Integer> ids) {
        int result = dynamicConfigMapper.deleteByIds(ids);
        return result;
    }

    @Override
    public int addCurve(CurveConfigAdd vo) {
        int result = CommonConstant.ZERO;
        try {
            deleteCurve(vo);
            CurveConfig config = new CurveConfig();
            BeanUtils.copyProperties(vo,config);
            result = curveConfigMapper.insertOne(config);
            log.info("插入曲线配置结果,{}",result);
            List<DynamicConfig> list = vo.getList();
            if(!list.isEmpty()){
                result = dynamicConfigMapper.insertList(list);
                log.info("插入动态配置结果,{}",result);
                List<CurveConfigRelation> relationList = new ArrayList<>();
                CurveConfigRelation relation = null;
                for (DynamicConfig d:list) {
                    relation = new CurveConfigRelation();
                    relation.setCurveId(config.getId());
                    relation.setDynamicConfigId(d.getId());
                    relationList.add(relation);
                }
                result = relationMapper.insertList(relationList);
                log.info("插入曲线管理关系结果,{}",result);
            }
        }catch (Exception e){
            log.error("插入曲线异常{}",e.getMessage());
        }
        return result;
    }

    @Override
    public int addCurveList(List<CurveConfigAdd> list) {
        int result = CommonConstant.ZERO;
        if(list.isEmpty()){
            log.info("新增曲线集合为空");
            return result;
        }
        deleteCurve(list.get(0));
        list = list.stream().filter(i->i.getCurveType()!=null).collect(Collectors.toList());
        if(list.isEmpty()){
            return result;
        }
        List<CurveConfig> curveConfigList = new ArrayList<>();
        List<CurveConfig> updateList = new ArrayList<>();
        List<CurveConfig> insertList = new ArrayList<>();
        CurveConfig config = null;
        for (CurveConfigAdd c:list) {
            //curveName 设置多语言翻译 20250821
            TranslateName translate = getNameLanguage(c.getCurveName());
            c.setCurveNameEn(translate.getNameEn());
            c.setCurveNameFra(translate.getNameFra());
            c.setCurveNameSpa(translate.getNameSpa());
            c.setCurveNameDe(translate.getNameDe());
            c.setCurveNamePl(translate.getNamePl());
            c.setCurveNameAra(translate.getNameAra());
            config = new CurveConfig();
            BeanUtils.copyProperties(c,config);
            if(c.getId() == null){
                insertList.add(config);
            }else{
                updateList.add(config);
            }
        }
//        result = curveConfigMapper.insertList(curveConfigList);
//        log.info("插入曲线配置结果,{}",result);
        if(!insertList.isEmpty()){
            result = curveConfigMapper.insertList(insertList);
            log.info("新增曲线配置：{}",result);
        }
        if(!updateList.isEmpty()){
            result = curveConfigMapper.updateList(updateList);
            log.info("新增(更新)曲线配置：{}",result);
        }
        curveConfigList.addAll(updateList);
        curveConfigList.addAll(insertList);
        int len = list.size();
        Integer id = null;
        for (int i = 0; i < len; i++) {
            id = curveConfigList.get(i).getId();
            list.get(i).setId(id);
            List<DynamicConfig> dList = list.get(i).getList();
            if(null != dList && !dList.isEmpty()){
                dList.stream().forEach(s->{
                    TranslateName translate = getNameLanguage(s.getColName());
                    s.setColNameEn(translate.getNameEn());
                    s.setColNameFra(translate.getNameFra());
                    s.setColNameSpa(translate.getNameSpa());
                    s.setColNameDe(translate.getNameDe());
                    s.setColNamePl(translate.getNamePl());
                    s.setColNameAra(translate.getNameAra());
                });
                //动态配置点国际化
                result = dynamicConfigMapper.insertList(dList);
                log.info("插入动态配置结果,{}",result);
                List<CurveConfigRelation> relationList = new ArrayList<>();
                CurveConfigRelation relation = null;
                for (DynamicConfig d:dList) {
                    relation = new CurveConfigRelation();
                    relation.setCurveId(id);
                    relation.setDynamicConfigId(d.getId());
                    relationList.add(relation);
                }
                result = relationMapper.insertList(relationList);
                log.info("插入曲线管理关系结果,{}",result);
            }
        }
        return result;
    }

    @Override
    public List<CurveConfigQueryResp> queryCurveConfig(DynamicConfigQuery vo) {
        List<CurveConfigResp> curveConfigResps = curveConfigMapper.selectByParam(vo);
        LinkedHashMap<Integer, List<CurveConfigResp>> collect = curveConfigResps.stream().collect(Collectors.groupingBy(i -> i.getId(), LinkedHashMap::new, Collectors.toList()));
        List<CurveConfigQueryResp> resultList = new ArrayList<>();
        for (Map.Entry<Integer, List<CurveConfigResp>> m:collect.entrySet()) {
            CurveConfigQueryResp config = new CurveConfigQueryResp();
            List<CurveConfigResp> value = m.getValue();
            BeanUtils.copyProperties(value.get(0),config);
            List<DynamicConfigResp> list = new ArrayList<>();
            for (CurveConfigResp r:value) {
                if(r.getSrcId()==null || r.getCol()==null){
                    continue;
                }
                DynamicConfigResp dynamicConfig = new DynamicConfigResp();
                BeanUtils.copyProperties(r,dynamicConfig);
                dynamicConfig.setFlgId(r.getSrcId()+r.getCol());
                list.add(dynamicConfig);
            }
            config.setList(list);
            resultList.add(config);
        }
        return resultList;
    }

    /**
     * 删除曲线所有信息
     * @param vo
     * @return
     */
    private int deleteCurve(CurveConfigAdd vo){
        int result = CommonConstant.ZERO;
        DynamicConfigQuery dynamicConfigQuery = new DynamicConfigQuery();
        BeanUtils.copyProperties(vo,dynamicConfigQuery);
        dynamicConfigQuery.setIsHide(null);
        List<CurveConfigResp> curveConfigResps = curveConfigMapper.selectByParam(dynamicConfigQuery);
        List<Integer> ids = curveConfigResps.stream().map(CurveConfigResp::getId).collect(Collectors.toList());
        if(!ids.isEmpty()){
            result = curveConfigMapper.deleteByIds(ids);
            log.info("删除曲线结果：{}",result);
            if(result>0){
                result = dynamicConfigMapper.deleteByCurveIds(ids);
                log.info("删除曲线对应点结果：{}",result);
            }
            if(result>0){
                result = relationMapper.deleteByCurveIds(ids);
                log.info("删除曲线对应点结果：{}",result);
            }
        }
        return result;
    }

    @Override
    public int addPointList(List<PointConfigAdd> list) {
        int result = CommonConstant.ZERO;
        try {
            if(list.isEmpty()){
                log.info("新增配置点集合为空");
                return result;
            }
            PointConfigAdd configAdd = new PointConfigAdd();
            BeanUtils.copyProperties(list.get(0),configAdd);
            deletePoint(configAdd);
            //系数偏移量设置默认值
//            list.stream().forEach(i->{
//                if(i.getOffsetValue()==null){
//                    i.setOffsetValue(BigDecimal.ZERO);
//                }
//                if(i.getFactor()==null){
//                    i.setFactor(BigDecimal.ONE);
//                }
//            });
            List<PointConfig> pointList = new ArrayList<>();
            PointConfig pointConfig = null;
            list = list.stream().filter(i->i.getPointType()!=null).collect(Collectors.toList());
            if(list.isEmpty()){
                return result;
            }
            List<PointConfig> updateList = new ArrayList<>();
            List<PointConfig> insertList = new ArrayList<>();
            int srcLen = list.size();
            PointConfigAdd srcPoint = null;
            List<Integer> updateIds = new ArrayList<>();
            for (int i = 0; i < srcLen; i++) {
                srcPoint = list.get(i);
                if(srcPoint.getOffsetValue()==null){
                    srcPoint.setOffsetValue(BigDecimal.ZERO);
                }
                if(srcPoint.getFactor()==null){
                    srcPoint.setFactor(BigDecimal.ONE);
                }
                //前端不传排序的情况下，默认按照接收的顺序排
                if(srcPoint.getSort()==null){
                    srcPoint.setSort(i);
                }
                //name defaultValue 设置多语言翻译 20250821
                TranslateName translate = getNameLanguage(srcPoint.getName());
                srcPoint.setNameEn(translate.getNameEn());
                srcPoint.setNameFra(translate.getNameFra());
                srcPoint.setNameSpa(translate.getNameSpa());
                srcPoint.setNameDe(translate.getNameDe());
                srcPoint.setNamePl(translate.getNamePl());
                srcPoint.setNameAra(translate.getNameAra());
                if(StringUtil.isNotBlank(srcPoint.getDefaultValue())){
                    TranslateName translateDe = getNameLanguage(srcPoint.getDefaultValue());
                    srcPoint.setDefaultValueEn(translateDe.getNameEn());
                    srcPoint.setDefaultValueFra(translateDe.getNameFra());
                    srcPoint.setDefaultValueSpa(translateDe.getNameSpa());
                    srcPoint.setDefaultValueDe(translateDe.getNameDe());
                    srcPoint.setDefaultValuePl(translateDe.getNamePl());
                    srcPoint.setDefaultValueAra(translateDe.getNameAra());
                }
                pointConfig = new PointConfig();
                BeanUtils.copyProperties(srcPoint,pointConfig);
                if(srcPoint.getId()==null){
                    insertList.add(pointConfig);
                }else{
                    updateIds.add(srcPoint.getId());
                    updateList.add(pointConfig);
                }
            }
//            for (PointConfigAdd p:list) {
//                pointConfig = new PointConfig();
//                BeanUtils.copyProperties(p,pointConfig);
//                pointList.add(pointConfig);
//            }
//            result = pointConfigMapper.insertList(pointList);
            if(!insertList.isEmpty()){
                result = pointConfigMapper.insertList(insertList);
                log.info("新增动态点配置：{}",result);
            }
            if(!updateList.isEmpty()){
                result = pointConfigMapper.updateList(updateList);
                int len  = updateList.size();
                for (int i = 0; i < len; i++) {
                    updateList.get(i).setId(updateIds.get(i));
                }
                log.info("新增（更新）动态点配置：{}",result);
            }
            pointList.addAll(updateList);
            pointList.addAll(insertList);
            pointList = pointList.stream().sorted((s,y)->{
                int count = 0;
                if(s.getSort()!=null && y.getSort()!=null){
                    count = s.getSort().compareTo(y.getSort());
                }
                return count;
            }).collect(Collectors.toList());
            List<PointConfigRelation> relationList = new ArrayList<>();
            PointConfigRelation relation = null;
            int len = pointList.size();
            for (int i = 0; i < len; i++) {
                list.get(i).setId(pointList.get(i).getId());
                List<DynamicConfig> dynamicConfigs = list.get(i).getList();
                //插入动态配置点
                if(!dynamicConfigs.isEmpty()){
                    dynamicConfigs.stream().forEach(s->{
                        TranslateName translate = getNameLanguage(s.getColName());
                        s.setColNameEn(translate.getNameEn());
                        s.setColNameFra(translate.getNameFra());
                        s.setColNameSpa(translate.getNameSpa());
                        s.setColNameDe(translate.getNameDe());
                        s.setColNamePl(translate.getNamePl());
                        s.setColNameAra(translate.getNameAra());
                    });
                    result = dynamicConfigMapper.insertList(dynamicConfigs);
                    for (DynamicConfig d:dynamicConfigs) {
                        relation = new PointConfigRelation();
                        relation.setPointId(pointList.get(i).getId());
                        relation.setDynamicConfigId(d.getId());
                        relationList.add(relation);
                    }
                }
            }
            //插入关联点
            result = pointRelationMapper.insertList(relationList);
            log.info("插入关联关系点结果:{}",result);

            List<PointConfigAdd> twoList = list.stream().filter(i -> CommonConstant.TWO.equals(i.getPointType()) || CommonConstant.ELEVEN.equals(i.getPointType())).collect(Collectors.toList());
            List<PointConfigAdd> threeList = list.stream().filter(i -> CommonConstant.THREE.equals(i.getPointType())).collect(Collectors.toList());
            //一点多义
            if(!twoList.isEmpty()){
                List<PointPolysemyConfig> pList = new ArrayList<>();
                for (PointConfigAdd p:twoList) {
                    p.getPolysemyList().forEach(i->i.setPointId(p.getId()));
                    pList.addAll(p.getPolysemyList());
                }
                //name 设置多语言翻译 20250821
                pList.stream().forEach(i->{
                    TranslateName translate = getNameLanguage(i.getName());
                    i.setNameEn(translate.getNameEn());
                    i.setNameFra(translate.getNameFra());
                    i.setNameSpa(translate.getNameSpa());
                    i.setNameDe(translate.getNameDe());
                    i.setNamePl(translate.getNamePl());
                    i.setNameAra(translate.getNameAra());
                });
                result = polysemyMapper.insertList(pList);
                log.info("插入一点多义表结果:{}",result);
            }
            //拆电芯
            if(!threeList.isEmpty()){
                List<PointDisassembleConfig> pList = new ArrayList<>();
                for (PointConfigAdd p:threeList) {
                    p.getDisassemble().setPointId(p.getId());
                    pList.add(p.getDisassemble());
                }
                result = disassembleMapper.insertList(pList);
                log.info("插入拆电芯结果:{}",result);
            }

        }catch (Exception e){
            log.error("批量插入点异常{}",e.getMessage());
        }
        return result;
    }

    @Override
    public List<PointConfigResultResp> pointList(PointConfigQuery vo) {
        List<PointConfigResultResp> pointConfigResultList = pointConfigMapper.selectByParamNew(vo);
        //一点多义
        List<Integer> polysemyList = pointConfigResultList.stream().filter(i -> CommonConstant.TWO.equals(i.getPointType()) || CommonConstant.ELEVEN.equals(i.getPointType())).map(PointConfigResultResp::getId).distinct().collect(Collectors.toList());
        Map<Integer, List<PointPolysemyConfig>> vMap = new HashMap<>();
        if(!polysemyList.isEmpty()){
            List<PointPolysemyConfig> list = polysemyMapper.selectByPointIds(polysemyList,vo.getLang());
            vMap = list.stream().collect(Collectors.groupingBy(PointPolysemyConfig::getPointId));
        }
        //拆电芯
        Map<Integer,List<PointDisassembleConfig>> disassembleMap = new HashMap<>();
        List<Integer> disassembleList = pointConfigResultList.stream().filter(i -> CommonConstant.THREE.equals(i.getPointType())).map(PointConfigResultResp::getId).distinct().collect(Collectors.toList());
        if(!disassembleList.isEmpty()){
            List<PointDisassembleConfig> list = disassembleMapper.selectByPointIds(disassembleList);
            disassembleMap = list.stream().collect(Collectors.groupingBy(PointDisassembleConfig::getPointId));
        }
        if(vMap.size()>0 || disassembleMap.size()>0){
            for (PointConfigResultResp p:pointConfigResultList) {
                if(vMap.get(p.getId())!=null){
                    p.setPolysemyList(vMap.get(p.getId()));
                }else if(disassembleMap.get(p.getId())!=null){
                    p.setDisassemble(disassembleMap.get(p.getId()).get(0));
                }
            }
        }
        return pointConfigResultList;
    }

    /**
     * 删除点
     * @param vo
     * @return
     */
    private int deletePoint(PointConfigAdd vo){
        int result = CommonConstant.ZERO;
        PointConfigQuery pointConfigQuery = new PointConfigQuery();
        BeanUtils.copyProperties(vo,pointConfigQuery);
        List<PointConfigResp> pointConfigResps = pointConfigMapper.selectByParam(pointConfigQuery);
        List<Integer> ids = pointConfigResps.stream().map(PointConfigResp::getId).collect(Collectors.toList());
        if(!ids.isEmpty()){
            result = pointConfigMapper.deleteByIds(ids);
            log.info("删除配置点结果：{}",result);
            if(result>0){
                result = dynamicConfigMapper.deleteByPointIds(ids);
                log.info("删除配置点对应点结果：{}",result);
            }
            if(result>0){
                result = pointRelationMapper.deleteByPointIds(ids);
                log.info("删除配置点关联关系：{}",result);
            }
            result = polysemyMapper.deleteByPointIds(ids);
            log.info("删除多义关系：{}",result);
            result = disassembleMapper.deleteByPointIds(ids);
            log.info("删除拆分详细表关系：{}",result);
        }
        return result;
    }

    @Override
    public List<PointConfigDataResp> getPointConfigData(PointConfigQuery vo) {
        List<PointConfigResultResp> pointConfigResultList = pointConfigMapper.selectByParamNew(vo);
        //一点多义
        List<Integer> polysemyList = pointConfigResultList.stream().filter(i -> CommonConstant.TWO.equals(i.getPointType())).map(PointConfigResultResp::getId).distinct().collect(Collectors.toList());
        Map<String, String> vMap = new HashMap<>();
        if(!polysemyList.isEmpty()){
            List<PointPolysemyConfig> list = polysemyMapper.selectByPointIds(polysemyList,vo.getLang());
            vMap = list.stream().filter(s->s.getValue()!=null&&s.getName()!=null).collect(Collectors.toMap(s -> s.getPointId() + "," + s.getValue().intValue(), s -> s.getName(), (k1, k2) -> k1));
        }
        //范围内的一点多义
        List<Integer> rangePolysemyList = pointConfigResultList.stream().filter(i -> CommonConstant.ELEVEN.equals(i.getPointType())).map(PointConfigResultResp::getId).distinct().collect(Collectors.toList());
        Map<Integer, List<PointPolysemyConfig>> rMap = new HashMap<>();
        if(!rangePolysemyList.isEmpty()){
            List<PointPolysemyConfig> list = polysemyMapper.selectByPointIds(rangePolysemyList,vo.getLang());
            rMap = list.stream().filter(s -> s.getValue() != null && s.getName() != null && s.getSymbol() != null).collect(Collectors.groupingBy(PointPolysemyConfig::getPointId));
        }
        //拆电芯
        Map<Integer,Integer> disassembleMap = new HashMap<>();
        List<Integer> disassembleList = pointConfigResultList.stream().filter(i -> CommonConstant.THREE.equals(i.getPointType())).map(PointConfigResultResp::getId).distinct().collect(Collectors.toList());
        if(!disassembleList.isEmpty()){
            List<PointDisassembleConfig> pointDisassembleConfigs = disassembleMapper.selectByPointIds(disassembleList);
            disassembleMap = pointDisassembleConfigs.stream().collect(Collectors.toMap(s->s.getPointId(),s->s.getValue(),(k1,k2)->k2));
        }
        List<PointConfigDataResp> resultList = new ArrayList<>();
        Integer id = null;
        for (PointConfigResultResp m:pointConfigResultList) {
            id = m.getId();
            PointConfigDataResp resp = new PointConfigDataResp();
            List<DynamicConfig> list = m.getList();
            if(!list.isEmpty()){
                BeanUtils.copyProperties(list.get(0),resp);
            }
            resp.setName(m.getName());
            resp.setId(id);
            resp.setPermissionId(m.getPermissionId());
            resp.setPageLocation(m.getPageLocation());
            resp.setDivLocation(m.getDivLocation());
            resp.setPointType(m.getPointType());
            resp.setDeviceId(m.getDeviceId());
            resp.setSort(m.getSort());
            resp.setStationId(m.getStationId());
            resp.setOffsetValue(m.getOffsetValue());
            resp.setFactor(m.getFactor());
            //虚拟节点可配，其余节点不可配
            resp.setIsConfig(CommonConstant.ZERO);
            if(resp.getDeviceType()!=null&&resp.getDeviceType().contains(DeviceTypeConstant.VM_NODE)){
                resp.setIsConfig(CommonConstant.ONE);
            }
            String value = null;
            BigDecimal val = null;
            boolean flag = true;
            for (DynamicConfig p:list) {
                String key = p.getDeviceType()+":"+m.getStationId()+":"+p.getSrcId();
                DeviceTransfer deviceTransfer = (DeviceTransfer)redisService.hget(key, p.getCol());
                if(deviceTransfer!=null){
                    switch (m.getPointType()){
                        case 1:
                            //多点合一
                            if(BigDecimal.ONE.compareTo(deviceTransfer.getValue())==0){
                                if(value==null){
                                    value = p.getColName();
                                }else{
                                    value = CommonConstant.DATA_ERROR;
                                }
                            }
                            break;
                        case 2:
                            //一点多义
                            String s = vMap.get(id + "," + deviceTransfer.getValue());
                            if(null != s){
                                value = s;
                            }
                            break;
                        case 3:
                            //拆电芯位置
                            Integer sVal = disassembleMap.get(id);
                            int dataVal = deviceTransfer.getValue().intValue();
                            //组号
                            value = String.valueOf(dataVal % sVal== CommonConstant.ZERO ? dataVal / sVal : (dataVal / sVal + CommonConstant.ONE));
                            PointConfigDataResp bmu = getPointConfigDataResp(resp,CommonConstant.BMU_NUM,value);
                            resultList.add(bmu);
                            //电芯位置
                            value = String.valueOf(dataVal % sVal == CommonConstant.ZERO ? sVal : dataVal % sVal);
                            PointConfigDataResp box = getPointConfigDataResp(resp,CommonConstant.BOX_NUM,value);
                            resultList.add(box);
                            flag = false;
                            break;
                        case 4:
                            //自算尖峰平谷
                            if(!list.isEmpty()){
                                getEarningsCalculate(resultList, resp);
                            }
                            flag = false;
                            break;
                        case 5:
                            //算差值
                            if(val==null){
                                val = deviceTransfer.getValue();
                            }else{
                                val = val.subtract(deviceTransfer.getValue());
                            }
                            break;
                        case 7:
                            //汇总值
                            if(val==null){
                                val = deviceTransfer.getValue();
                            }else{
                                val = val.add(deviceTransfer.getValue());
                            }
                            break;
                        case 8:
                            //自算日充
                            BigDecimal dayChargeDeal = getDayChargeDeal(p.getCol(),m.getStationId(),p.getSrcId(), DataCollectConstant.Elec_Meter.TOTAL_CHARGE);
                            if(dayChargeDeal != null){
                                if(val==null){
                                    val = dayChargeDeal;
                                }else{
                                    val = val.add(dayChargeDeal);
                                }
                            }
                            break;
                        case 9:
                            //自算日放电
                            BigDecimal dayDischargeDeal = getDayChargeDeal(p.getCol(),m.getStationId(),p.getSrcId(),DataCollectConstant.Elec_Meter.TOTAL_DISCHARGE);
                            if(dayDischargeDeal != null){
                                if(val==null){
                                    val = dayDischargeDeal;
                                }else{
                                    val = val.add(dayDischargeDeal);
                                }
                            }
                            break;
                        case 11:
                            //一点多义
                            List<PointPolysemyConfig> pointPolysemyConfigs = rMap.get(id);
                            if(pointPolysemyConfigs!=null){
                                for (PointPolysemyConfig vp:pointPolysemyConfigs) {
                                    String exp = CommonConstant.ALPHABET.a + vp.getSymbol()+vp.getValue();
                                    Expression expression = AviatorEvaluator.compile(exp);
                                    Map<String,Object> map = new HashMap<>();
                                    map.put(CommonConstant.ALPHABET.a ,deviceTransfer.getValue());
                                    Object execute = expression.execute(map);
                                    if(CommonConstant.TRUE.equals(execute.toString())){
                                        value = vp.getName();
                                        break;
                                    }
                                }
                            }
                            break;
                        default:
                            //普通点
                            val = deviceTransfer.getValue();
                            break;
                    }
                }
                else{
                    //普通点，且没设置默认志
                    if(CommonConstant.ZERO.equals(m.getPointType()) && m.getDefaultValue()==null){
                        val = BigDecimal.ZERO;
                    }
                }
            }
            //自算尖峰平谷
            if(CommonConstant.FOUR.equals(m.getPointType())){
                getEarningsCalculate(resultList, resp);
                flag = false;
            }else if(CommonConstant.TEN.equals(m.getPointType())){
                //自定义名称
                value =  m.getName();
            }
            if(flag){
                if(null != val){
                    val = val.multiply(m.getFactor()==null?BigDecimal.ONE:m.getFactor()).add(m.getOffsetValue()==null?BigDecimal.ZERO:m.getOffsetValue());
                    value = val.setScale(2,BigDecimal.ROUND_HALF_UP).toString();
                }
                if(null == value){
                    resp.setCol(null);
                    resp.setColName(null);
                    resp.setSrcId(null);
                    resp.setDeviceType(null);
                    value = m.getDefaultValue();
                }
                resp.setValue(value);
                resultList.add(resp);
            }
        }
        return resultList;
    }

    @Override
    public int syncDynamicConfig(SyncDynamicConfigParam vo) {
        int result = CommonConstant.ZERO;
        List<SyncDynamicDeviceConfig> desDeviceIdList = vo.getList();
        /*****************因为前端组合参数错误，未能按照要求的方式组织参数，故而多出以下步骤*****开始***************/
        LinkedHashMap<Integer,List<SyncDynamicDeviceMapping>>  syncDynamicDeviceConfigMap = new LinkedHashMap<>();
        if(desDeviceIdList != null){
            for (SyncDynamicDeviceConfig i:desDeviceIdList) {
                List<SyncDynamicDeviceMapping> syncDynamicDeviceMappings = syncDynamicDeviceConfigMap.get(i.getDesDeviceId());
                if(syncDynamicDeviceMappings != null){
                    syncDynamicDeviceMappings.addAll(i.getList());
                }else{
                    syncDynamicDeviceMappings = i.getList();
                }
                syncDynamicDeviceConfigMap.put(i.getDesDeviceId(),syncDynamicDeviceMappings);
            }
        }
        if(!syncDynamicDeviceConfigMap.isEmpty()){
            desDeviceIdList = syncDynamicDeviceConfigMap.entrySet().stream().map(e -> new SyncDynamicDeviceConfig(e.getKey(), e.getValue())).collect(Collectors.toList());
        }
        /***********************************结束*********************/
        Integer srcStationId = vo.getSrcStationId();
        Integer permissionId = vo.getPermissionId();
        Integer deviceId = vo.getSrcDeviceId();
        //同步曲线
        DynamicConfigQuery dynamicConfigQuery = new DynamicConfigQuery();
        dynamicConfigQuery.setStationId(srcStationId);
        dynamicConfigQuery.setPermissionId(permissionId);
        dynamicConfigQuery.setDeviceId(deviceId);
        List<CurveConfigQueryResp> curveConfigList = queryCurveConfig(dynamicConfigQuery);
        if(!curveConfigList.isEmpty()){
            List<CurveConfigAdd> curveAddList = new ArrayList<>();
            if(desDeviceIdList == null){
                getCurveAddList(vo, curveConfigList, curveAddList,null,null);
                if(!curveAddList.isEmpty()){
                    CurveConfigAdd curveConfigAdd = new CurveConfigAdd();
                    curveConfigAdd.setStationId(vo.getDesStationId());
                    deleteCurve(curveConfigAdd);
                }
            }else{
                //站内拷贝
                for (SyncDynamicDeviceConfig d:desDeviceIdList) {
                    List<SyncDynamicDeviceMapping> list = d.getList();
                    Map<Integer, SyncDynamicDeviceMapping> map = list.stream().collect(Collectors.toMap(SyncDynamicDeviceMapping::getSrcSrcId, Function.identity(), (k1, k2) -> k1));
                    getCurveAddList(vo, curveConfigList, curveAddList,d.getDesDeviceId(),map);
                }
            }
            result = addCurveList(curveAddList);
            log.info("一键复制，同步曲线结果:{}",result);
        }
        //同步点
        PointConfigQuery pointConfigQuery = new PointConfigQuery();
        pointConfigQuery.setStationId(srcStationId);
        pointConfigQuery.setPermissionId(permissionId);
        pointConfigQuery.setDeviceId(deviceId);
        List<PointConfigResultResp> pointList = pointList(pointConfigQuery);
        if(!pointList.isEmpty()){
            List<PointConfigAdd> pointAddList = new ArrayList<>();
            if(desDeviceIdList == null){
                getConfigAddList(vo, pointList, pointAddList,null,null);
                if(!pointAddList.isEmpty()){
                    PointConfigAdd configAdd = new PointConfigAdd();
                    configAdd.setStationId(vo.getDesStationId());
                    deletePoint(configAdd);
                }
            }else{
                //站内拷贝
                for (SyncDynamicDeviceConfig d:desDeviceIdList) {
                    List<SyncDynamicDeviceMapping> list = d.getList();
                    Map<Integer, SyncDynamicDeviceMapping> map = list.stream().collect(Collectors.toMap(SyncDynamicDeviceMapping::getSrcSrcId, Function.identity(), (k1, k2) -> k1));
                    getConfigAddList(vo, pointList, pointAddList,d.getDesDeviceId(),map);
                }
                if(!pointAddList.isEmpty()){
                    PointConfigAdd configAdd = new PointConfigAdd();
                    configAdd.setStationId(pointAddList.get(0).getStationId());
                    configAdd.setPermissionId(pointAddList.get(0).getPermissionId());
                    configAdd.setDeviceId(pointAddList.get(0).getDeviceId());
                    deletePoint(configAdd);
                }
            }
            result = addPointList(pointAddList);
            log.info("一键复制，同步配置点结果:{}",result);
        }
        return result;
    }

    @Override
    public List<DeviceRespVO> dynamicConfigDevice(SyncDynamicConfigDeviceQuery vo) {
        List<DeviceRespVO> resultList = new ArrayList<>();
        //所有点
        PointConfigQuery pointConfigQuery = new PointConfigQuery();
        BeanUtils.copyProperties(vo,pointConfigQuery);
        List<PointConfigResp> pointConfigResultList = pointConfigMapper.selectByParam(pointConfigQuery);
        List<Integer> pList = pointConfigResultList.stream().map(PointConfigResp::getSrcId).distinct().collect(Collectors.toList());
        //所有线
        DynamicConfigQuery dynamicConfigQuery = new DynamicConfigQuery();
        BeanUtils.copyProperties(vo,dynamicConfigQuery);
        List<CurveConfigResp> curveConfigResps = curveConfigMapper.selectByParam(dynamicConfigQuery);
        List<Integer> cList = curveConfigResps.stream().map(CurveConfigResp::getSrcId).distinct().collect(Collectors.toList());
        List<Integer> srcIdList = new ArrayList<>();
        srcIdList.addAll(pList);
        srcIdList.addAll(cList);
        if(!srcIdList.isEmpty()){
            DeviceReqVO deviceReqVO = new DeviceReqVO();
            deviceReqVO.setStationId(vo.getStationId());
            deviceReqVO.setSrcIdList(srcIdList);
            resultList = deviceService.getList(deviceReqVO);
        }
        return resultList;
    }

    @Override
    public int addDynamicConfigTitle(DynamicConfigTitle vo) {
        int result = CommonConstant.ZERO;
        if(vo.getId()!=null){
            result = configTitleMapper.updateById(vo);
        }else{
            result = configTitleMapper.insertOne(vo);
        }
        return result;
    }

    @Override
    public List<DynamicConfigTitle> queryDynamicConfigTitle(DynamicConfigTitle vo) {
        List<DynamicConfigTitle> dynamicConfigTitles = configTitleMapper.selectByParam(vo);
        return dynamicConfigTitles;
    }

    @Override
    public int delDynamicConfigTitle(DynamicConfigTitle vo) {
        int result = configTitleMapper.deleteById(vo.getId());
        return result;
    }

    @Override
    public String getNameByLang(String name,String lang){
        TranslateName translate = getNameLanguage(name);
        switch (lang){
            case CommonConstant.langTemp.EN_US:
                return translate.getNameEn();
            case CommonConstant.langTemp.DE_DE:
                return translate.getNameDe();
            case CommonConstant.langTemp.ES_ES:
                return translate.getNameSpa();
            case CommonConstant.langTemp.AR_EG:
                return translate.getNameAra();
            case CommonConstant.langTemp.PL_PL:
                return translate.getNamePl();
            case CommonConstant.langTemp.FR_FR:
                return translate.getNameFra();
            case CommonConstant.langTemp.ZH_CN:
                return translate.getName();
        }
        return null;
    }


    @Override
    public TranslateName getNameLanguage(String name) {
        // 英语
        String nameEn = null;
        // 法语
        String nameFra = null;
        // 西班牙语
        String nameSpa = null;
        // 德语
        String nameDe = null;
        // 波兰语
        String namePl = null;
        // 阿拉伯语
        String nameAra = null;
        // 查询数据库中  预先翻译的中文字段 语言
        TranslateName vo = translateNameMapper.selectNameLang(name);
        TranslateName translate = new TranslateName();
        boolean flag = false;
        if(vo == null){
            nameEn = TranslateUtils.translate(name,CommonConstant.lang.EN);
            nameFra = TranslateUtils.translate(name,CommonConstant.lang.FRA);
            nameSpa = TranslateUtils.translate(name,CommonConstant.lang.SPA);
            nameDe = TranslateUtils.translate(name,CommonConstant.lang.DE);
            namePl = TranslateUtils.translate(name,CommonConstant.lang.PL);
            nameAra = TranslateUtils.translate(name,CommonConstant.lang.ARA);
            // 插入中文预翻译表
            translate.setName(name);
            translate.setNameEn(nameEn);
            translate.setNameFra(nameFra);
            translate.setNameSpa(nameSpa);
            translate.setNameDe(nameDe);
            translate.setNamePl(namePl);
            translate.setNameAra(nameAra);
            CompletableFuture.runAsync(()->{
                translateNameMapper.insert(translate);
            });
            return translate;
        }else{
            if(StringUtil.isEmpty(vo.getNameEn())){
                vo.setNameEn(TranslateUtils.translate(name,CommonConstant.lang.EN));
                flag = true;
            }
            if(StringUtil.isEmpty(vo.getNameFra())){
                vo.setNameFra(TranslateUtils.translate(name,CommonConstant.lang.FRA));
                flag = true;
            }
            if(StringUtil.isEmpty(vo.getNameSpa())){
                vo.setNameSpa(TranslateUtils.translate(name,CommonConstant.lang.SPA));
                flag = true;
            }
            if(StringUtil.isEmpty(vo.getNameDe())){
                vo.setNameDe(TranslateUtils.translate(name,CommonConstant.lang.DE));
                flag = true;
            }
            if(StringUtil.isEmpty(vo.getNamePl())){
                vo.setNamePl(TranslateUtils.translate(name,CommonConstant.lang.PL));
                flag = true;
            }
            if(StringUtil.isEmpty(vo.getNameAra())){
                vo.setNameAra(TranslateUtils.translate(name,CommonConstant.lang.ARA));
                flag = true;
            }
            if(flag){
                CompletableFuture.runAsync(()->{
                    translateNameMapper.updateById(vo);
                });
            }
        }
        return vo;
    }


    private void getConfigAddList(SyncDynamicConfigParam vo, List<PointConfigResultResp> pointList, List<PointConfigAdd> pointAddList,Integer deviceId,Map<Integer, SyncDynamicDeviceMapping> map) {
        PointConfigAdd configAdd = null;
        for (PointConfigResultResp p: pointList) {
            configAdd = new PointConfigAdd();
            BeanUtils.copyProperties(p,configAdd);
            configAdd.setId(null);
            configAdd.setStationId(vo.getDesStationId());
            if(deviceId != null){
                configAdd.setDeviceId(deviceId);
            }
            p.getList().forEach(i->{i.setDeviceType(i.getDeviceType().replaceAll(String.valueOf(vo.getSrcStationId()),String.valueOf(vo.getDesStationId())));
                i.setStationId(vo.getDesStationId());
                String colName = i.getColName();
                if(colName.contains("/")){
                    String[] split = colName.split("/");
                    i.setColName(split[1]);
                }
                if(map != null){
                    SyncDynamicDeviceMapping syncDynamicDeviceMapping = map.get(i.getSrcId());
                    if(syncDynamicDeviceMapping!=null){
                        i.setSrcId(syncDynamicDeviceMapping.getDesSrcId());
                    }
                }
            });
            pointAddList.add(configAdd);
        }
    }

    private void getCurveAddList(SyncDynamicConfigParam vo, List<CurveConfigQueryResp> curveConfigList, List<CurveConfigAdd> curveAddList,Integer deviceId,Map<Integer, SyncDynamicDeviceMapping> map) {
        CurveConfigAdd configAdd;
        List<DynamicConfigResp> list;
        for (CurveConfigQueryResp c: curveConfigList) {
            List<DynamicConfig> dyList = new ArrayList<>();
            configAdd = new CurveConfigAdd();
            BeanUtils.copyProperties(c,configAdd);
            configAdd.setId(null);
            configAdd.setStationId(vo.getDesStationId());
            if(deviceId != null){
                configAdd.setDeviceId(deviceId);
            }
            list = c.getList();
            for (DynamicConfigResp s:list) {
                DynamicConfig d = new DynamicConfig();
                BeanUtils.copyProperties(s,d);
                d.setStationId(vo.getDesStationId());
                if(map==null){
                    d.setDeviceType(s.getDeviceType().replaceAll(String.valueOf(vo.getSrcStationId()),String.valueOf(vo.getDesStationId())));
                }else{
                    //站内拷贝
                    SyncDynamicDeviceMapping syMapping = map.get(s.getSrcId());
                    if(null != syMapping){
                        d.setDeviceType(syMapping.getDesDeviceType());
                        d.setSrcId(syMapping.getDesSrcId());
                    }
                }
                dyList.add(d);
            }
            configAdd.setList(dyList);
            curveAddList.add(configAdd);
        }
    }

    /**
     * 自算尖峰平谷
     * @param resultList
     * @param resp
     */
    private void getEarningsCalculate(List<PointConfigDataResp> resultList, PointConfigDataResp resp) {
        EarningsCalculateReq earningsCalculateReq = new EarningsCalculateReq();
        earningsCalculateReq.setStationId(resp.getStationId());
        List<EarningsCalculate> eList = earningsCalculateService.totalList(earningsCalculateReq);
        BigDecimal chargeTip = BigDecimal.ZERO;
        BigDecimal chargePeak = BigDecimal.ZERO;
        BigDecimal chargeFlat = BigDecimal.ZERO;
        BigDecimal chargeValley = BigDecimal.ZERO;
        BigDecimal chargeDeepValley = BigDecimal.ZERO;
        BigDecimal dischargeTip = BigDecimal.ZERO;
        BigDecimal dischargePeak = BigDecimal.ZERO;
        BigDecimal dischargeFlat = BigDecimal.ZERO;
        BigDecimal dischargeValley = BigDecimal.ZERO;
        BigDecimal dischargeDeepValley = BigDecimal.ZERO;
        Date d = new Date();
        for (EarningsCalculate e : eList) {
            if (CommonConstant.ZERO.equals(e.getType())) {
                //充电数据
                if (CommonConstant.RateType.TIP.equals(e.getRateType())) {
                    chargeTip = e.getElec();
                } else if (CommonConstant.RateType.PEAK.equals(e.getRateType())) {
                    chargePeak = e.getElec();
                } else if (CommonConstant.RateType.FLAT.equals(e.getRateType())) {
                    chargeFlat = e.getElec();
                } else if (CommonConstant.RateType.VALLEY.equals(e.getRateType())) {
                    chargeValley = e.getElec();
                } else if (CommonConstant.RateType.DEEP_VALLEY.equals(e.getRateType())) {
                    chargeDeepValley = e.getElec();
                }
            } else if (CommonConstant.ONE.equals(e.getType())) {
                //放电数据
                if (CommonConstant.RateType.TIP.equals(e.getRateType())) {
                    dischargeTip = e.getElec();
                } else if (CommonConstant.RateType.PEAK.equals(e.getRateType())) {
                    dischargePeak = e.getElec();
                } else if (CommonConstant.RateType.FLAT.equals(e.getRateType())) {
                    dischargeFlat = e.getElec();
                } else if (CommonConstant.RateType.VALLEY.equals(e.getRateType())) {
                    dischargeValley = e.getElec();
                } else if (CommonConstant.RateType.DEEP_VALLEY.equals(e.getRateType())) {
                    dischargeDeepValley = e.getElec();
                }
            }
        }
        PointConfigDataResp pr = countValue(resp, CommonConstant.POSITIVE+CommonConstant.ELE_TIP + CommonConstant.KWH, chargeTip);
        resultList.add(pr);
        pr = countValue(resp, CommonConstant.POSITIVE+CommonConstant.ELE_PEAK + CommonConstant.KWH, chargePeak);
        resultList.add(pr);
        pr = countValue(resp, CommonConstant.POSITIVE+CommonConstant.ELE_FLAT + CommonConstant.KWH, chargeFlat);
        resultList.add(pr);
        pr = countValue(resp, CommonConstant.POSITIVE+CommonConstant.ELE_VALLEY + CommonConstant.KWH, chargeValley);
        resultList.add(pr);
        pr = countValue(resp, CommonConstant.POSITIVE+CommonConstant.ELE_DEEP_VALLEY + CommonConstant.KWH, chargeDeepValley);
        resultList.add(pr);
        pr = countValue(resp, CommonConstant.NEGATIVE+CommonConstant.ELE_TIP + CommonConstant.KWH, dischargeTip);
        resultList.add(pr);
        pr = countValue(resp, CommonConstant.NEGATIVE+CommonConstant.ELE_PEAK + CommonConstant.KWH, dischargePeak);
        resultList.add(pr);
        pr = countValue(resp, CommonConstant.NEGATIVE+CommonConstant.ELE_FLAT + CommonConstant.KWH, dischargeFlat);
        resultList.add(pr);
        pr = countValue(resp, CommonConstant.NEGATIVE+CommonConstant.ELE_VALLEY + CommonConstant.KWH, dischargeValley);
        resultList.add(pr);
        pr = countValue(resp, CommonConstant.NEGATIVE+CommonConstant.ELE_DEEP_VALLEY + CommonConstant.KWH, dischargeDeepValley);
        resultList.add(pr);
    }

    private PointConfigDataResp countValue(PointConfigDataResp resp,String name,BigDecimal val) {
        val = val.multiply(resp.getFactor()==null?BigDecimal.ONE:resp.getFactor()).add(resp.getOffsetValue()==null?BigDecimal.ZERO:resp.getOffsetValue());
        String value = val.setScale(2,BigDecimal.ROUND_HALF_UP).toString();
        return getPointConfigDataResp(resp,name,value);
    }

    @NotNull
    private PointConfigDataResp getPointConfigDataResp(PointConfigDataResp resp,String name,String val) {
        PointConfigDataResp box = new PointConfigDataResp();
        box.setName(name);
        box.setDefaultValue(resp.getDefaultValue());
        box.setSort(resp.getSort());
        box.setPointType(resp.getPointType());
        box.setValue(val);
        box.setSensType(resp.getSensType());
        box.setFactor(resp.getFactor());
        box.setOffsetValue(resp.getOffsetValue());
        box.setStationId(resp.getStationId());
        box.setSensType(CommonConstant.TWO);
        return box;
    }

    private BigDecimal getDayChargeDeal(String col,Integer stationId,Integer srcId,String colAlias){
        MonitorQuery monitorQuery = new MonitorQuery();
        monitorQuery.setStationId(stationId);
        return outApiService.getDayChargeDeal(monitorQuery,srcId,col,colAlias);
    }
}
