package com.hdkj.lt.bf.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hdkj.lt.base.exception.BusinessException;
import com.hdkj.lt.bf.constants.TransferSchemeConstants;
import com.hdkj.lt.bf.entity.dto.EvaluationHeadDTO;
import com.hdkj.lt.bf.entity.dto.FhzgPlanTransferSchemeDTO;
import com.hdkj.lt.bf.entity.dto.FhzgPlanTransferSchemeStrategyScoreDTO;
import com.hdkj.lt.bf.entity.dto.StrategyConfigDetailDTO;
import com.hdkj.lt.bf.entity.vo.FhzgStrategyConfigDetailVO;
import com.hdkj.lt.bf.entity.vo.TransferSchemeStrategyScoreVO;
import com.hdkj.lt.bf.mapper.FhzgPlanTransferSchemeStrategyScoreMapper;
import com.hdkj.lt.bf.service.FhzgPlanStrategyService;
import com.hdkj.lt.bf.service.FhzgPlanTransferSchemeService;
import com.hdkj.lt.bf.service.IFhzgPlanTransferSchemeStrategyScoreService;
import com.hdkj.lt.core.bizms.modle.dto.TransferSchemeEvaluationReqDTO;
import com.hdkj.lt.core.bizms.modle.po.plan.FhzgPlanTransferScheme;
import com.hdkj.lt.core.bizms.modle.po.plan.FhzgPlanTransferSchemeStrategyScore;
import com.hdkj.lt.core.bizms.modle.po.plan.FhzgPlanTransferStrategyConfigDetail;
import com.hdkj.lt.core.sys.dao.SysDictMapper;
import com.hdkj.lt.core.sys.model.po.DicSingle;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * <p>
 * 转供方案策略得分表 服务实现类
 * </p>
 *
 * @author luorui
 * @since 2025-05-23
 */
@Service
@Slf4j
public class FhzgPlanTransferSchemeStrategyScoreServiceImpl extends ServiceImpl<FhzgPlanTransferSchemeStrategyScoreMapper, FhzgPlanTransferSchemeStrategyScore> implements IFhzgPlanTransferSchemeStrategyScoreService {

    @Autowired
    FhzgPlanStrategyService fhzgPlanStrategyService;

    @Autowired
    FhzgPlanTransferSchemeService fhzgPlanTransferSchemeService;

    @Autowired
    SysDictMapper sysDictMapper;

    private static final String SCHEME_EVALUATION_TAG = "scheme_evaluation_tag";
    private static final String LOSS_USERS = "lossUsers";
    private static final String TRANSFER_LOAD_RATIO = "transferLoadRatio";
    private static final String OPPOSITE_LINE_MAX_LOAD_RATE = "oppositeLineMaxLoadRate";
    private static final String SWITCH_OPERATION_TIMES = "switchOperationTimes";



    /**
     *
     * @author luorui
     * @date 2025/5/23 17:49
     * @discription 根据计划planId 查询计划下方案评分情况
     *
     **/
    @Override
    public TransferSchemeStrategyScoreVO getTransferSchemeStrategyScoreByPlanId(TransferSchemeEvaluationReqDTO transferSchemeEvaluationReqDTO) {
        if (Objects.isNull(transferSchemeEvaluationReqDTO.getPlanId())) {
            throw new BusinessException("计划编码为空planId");
        }
        //查询该计划使用的 策略表头
        List<FhzgPlanTransferStrategyConfigDetail> strategyConfigList = fhzgPlanStrategyService.getStrategyDetailByPlanId(transferSchemeEvaluationReqDTO.getPlanId());
        if (CollUtil.isEmpty(strategyConfigList)) {
            log.info("评分策略信息为空");
        }
        //查询策略版本名称
        String versionName = null;
        Integer transferStrategy = null;
        if (CollUtil.isNotEmpty(strategyConfigList)) {
            Long strategyId = strategyConfigList.get(0).getStrategyId();
            StrategyConfigDetailDTO dto = new StrategyConfigDetailDTO();
            dto.setStrategyId(strategyId);
            FhzgStrategyConfigDetailVO fhzgStrategyConfigDetailVO = fhzgPlanStrategyService.getStrategyconfigDetail(dto);
            versionName = Objects.isNull(fhzgStrategyConfigDetailVO) ? null : fhzgStrategyConfigDetailVO.getVersionName();
            transferStrategy = Objects.isNull(fhzgStrategyConfigDetailVO) ? null : fhzgStrategyConfigDetailVO.getTransferStrategy();
        }
        List<EvaluationHeadDTO> headDTOList = caseStrategyConfig(strategyConfigList);
        List<FhzgPlanTransferSchemeStrategyScoreDTO> fhzgPlanTransferSchemeStrategyScoreDTOList = baseMapper.getTransferSchemeStrategyScoreByPlanId(transferSchemeEvaluationReqDTO);
        TransferSchemeStrategyScoreVO transferSchemeStrategyScoreVO = new TransferSchemeStrategyScoreVO();
        transferSchemeStrategyScoreVO.setStrategyScoreList(fhzgPlanTransferSchemeStrategyScoreDTOList);
        transferSchemeStrategyScoreVO.setHeadList(headDTOList);
        transferSchemeStrategyScoreVO.setVersionName(versionName);
        transferSchemeStrategyScoreVO.setTransferStrategy(transferStrategy);
        return transferSchemeStrategyScoreVO;
    }


    /**
     *
     * @author luorui
     * @date 2025/5/23 18:33
     * @discription 查询方案评分并且打上标签
     *
     **/
    @Override
    public List<FhzgPlanTransferSchemeDTO> getTransferSchemeEvaluationListByPlanId(TransferSchemeEvaluationReqDTO transferSchemeEvaluationReqDTO) {
        if (Objects.isNull(transferSchemeEvaluationReqDTO.getPlanId())) {
            throw new BusinessException("计划编码为空planId");
        }
        //查询枚举值
        List<DicSingle> dicSingleList = sysDictMapper.getDictSingleByTypeName(SCHEME_EVALUATION_TAG);
        //Key->标签的code,V->标签对象
        Map<String, DicSingle> dicSingleMap = dicSingleList.stream().collect(Collectors.toMap(DicSingle::getValue, Function.identity(),(k1,k2)->k2));
        //K->方案编码 V->方案获得的标签集合
        Map<Long,List<DicSingle>> result = new HashMap<>();
        //查询所有方案的得分项
        List<FhzgPlanTransferSchemeStrategyScoreDTO> fhzgPlanTransferSchemeStrategyScoreDTOList = baseMapper.getTransferSchemeStrategyScoreByPlanId(transferSchemeEvaluationReqDTO);
        if(CollUtil.isNotEmpty(fhzgPlanTransferSchemeStrategyScoreDTOList)){
            //将得分项分别按照，损失户数最少，转出负荷最多，对侧线路负载率最低，开关次数最少 排序；
            //损失户数 降序
            List<FhzgPlanTransferSchemeStrategyScoreDTO> lossUserList = fhzgPlanTransferSchemeStrategyScoreDTOList.stream().sorted(Comparator.comparing(FhzgPlanTransferSchemeStrategyScoreDTO::getLossUsers,Comparator.nullsFirst(Integer::compareTo)).reversed()).collect(Collectors.toList());
            sortLossUsersEvaluation(lossUserList,result,dicSingleMap,LOSS_USERS);
            //转出负荷最多 降序
            List<FhzgPlanTransferSchemeStrategyScoreDTO> transferLoadRatioList = fhzgPlanTransferSchemeStrategyScoreDTOList.stream().sorted(Comparator.comparing(FhzgPlanTransferSchemeStrategyScoreDTO::getTransferLoadRatio,Comparator.nullsFirst(Integer::compareTo)).reversed()).collect(Collectors.toList());
            sortTransferLoadRatio(transferLoadRatioList,result,dicSingleMap,TRANSFER_LOAD_RATIO);
            //对侧线路负载率最低 降序
            List<FhzgPlanTransferSchemeStrategyScoreDTO> oppositeLineMaxLoadRateList = fhzgPlanTransferSchemeStrategyScoreDTOList.stream().sorted(Comparator.comparing(FhzgPlanTransferSchemeStrategyScoreDTO::getOppositeLineMaxLoadRate,Comparator.nullsFirst(Integer::compareTo)).reversed()).collect(Collectors.toList());
            sortOppositeLineMaxLoadRate(oppositeLineMaxLoadRateList,result,dicSingleMap,OPPOSITE_LINE_MAX_LOAD_RATE);
            //开关次数最少 降序
            List<FhzgPlanTransferSchemeStrategyScoreDTO> switchOperationTimesList = fhzgPlanTransferSchemeStrategyScoreDTOList.stream().sorted(Comparator.comparing(FhzgPlanTransferSchemeStrategyScoreDTO::getSwitchOperationTimes,Comparator.nullsFirst(Integer::compareTo)).reversed()).collect(Collectors.toList());
            sortSwitchOperationTimes(switchOperationTimesList,result,dicSingleMap,SWITCH_OPERATION_TIMES);
            // 对result中的每一项 数据标签进行排序
            result.forEach((k, v) -> {
                if (null != v) {
                    List<DicSingle> dicSingles = v.stream().sorted(Comparator.comparing(DicSingle::getSort)).collect(Collectors.toList());
                    //将标签按照一定顺序排序（字典表中的排序）
                    result.put(k,dicSingles);
                }
            });

        } else {
            log.info("未查询到方案评分信息planId:{}", transferSchemeEvaluationReqDTO.getPlanId());
        }
        //查询计划下的全部方案
        FhzgPlanTransferScheme fhzgPlanTransferScheme = new FhzgPlanTransferScheme();
        fhzgPlanTransferScheme.setPlanId(transferSchemeEvaluationReqDTO.getPlanId());
        List<FhzgPlanTransferSchemeDTO> fhzgPlanTransferSchemeDTOList = fhzgPlanTransferSchemeService.getTransferSchemeListByPlanId(fhzgPlanTransferScheme);
        if(CollUtil.isNotEmpty(fhzgPlanTransferSchemeDTOList)){
            fhzgPlanTransferSchemeDTOList.forEach(e->{
                List<DicSingle> tagList = result.get(e.getId());
                if(CollUtil.isNotEmpty(tagList)){
                    e.setSchemeEvaluationTag(tagList.get(0).getLabel());
                }
                e.setTotalTransfer(e.getTotalTransfer().multiply(new BigDecimal("1000")));
            });

        }
        return fhzgPlanTransferSchemeDTOList;
    }

    /**
     *
     * @author luorui
     * @date 2025/5/23 19:48
     * @discription 损失用户
     * @param list 排序好的集合
     * @param result 收集数据的集合
     * @param dicSingleMap 字典表集合
     * @param key 比较的指标编码
     **/
    private void sortLossUsersEvaluation(List<FhzgPlanTransferSchemeStrategyScoreDTO> list, Map<Long, List<DicSingle>> result, Map<String, DicSingle> dicSingleMap, String key) {
        if (list.size() > 0) {
            //list已经排序好了 处理可能并列的情况
            FhzgPlanTransferSchemeStrategyScoreDTO fhzgPlanTransferSchemeStrategyScoreDTO_0 = list.get(0);
            Integer lossUsers = fhzgPlanTransferSchemeStrategyScoreDTO_0.getLossUsers();
            for (FhzgPlanTransferSchemeStrategyScoreDTO fhzgPlanTransferSchemeStrategyScoreDTO : list) {
                if (ObjectUtil.equal(fhzgPlanTransferSchemeStrategyScoreDTO.getLossUsers(), lossUsers)) {
                    addTag(result, fhzgPlanTransferSchemeStrategyScoreDTO.getSchemeId(), dicSingleMap, key);
                } else {
                    //后一个元素不相同则结束循环
                    break;
                }
            }
        }
    }

    /**
     *
     * @author luorui
     * @date 2025/5/23 19:48
     * @discription 转出负荷最多 比较
     * @param list 排序好的集合
     * @param result 收集数据的集合
     * @param dicSingleMap 字典表集合
     * @param key 比较的指标编码
     **/
    private void sortTransferLoadRatio(List<FhzgPlanTransferSchemeStrategyScoreDTO> list, Map<Long, List<DicSingle>> result, Map<String, DicSingle> dicSingleMap, String key) {
        if (list.size() > 0) {
            //list已经排序好了 处理可能并列的情况
            FhzgPlanTransferSchemeStrategyScoreDTO fhzgPlanTransferSchemeStrategyScoreDTO_0 = list.get(0);
            Integer transferLoadRatio = fhzgPlanTransferSchemeStrategyScoreDTO_0.getTransferLoadRatio();
            for (FhzgPlanTransferSchemeStrategyScoreDTO fhzgPlanTransferSchemeStrategyScoreDTO : list) {
                if (ObjectUtil.equal(fhzgPlanTransferSchemeStrategyScoreDTO.getTransferLoadRatio(), transferLoadRatio)) {
                    addTag(result, fhzgPlanTransferSchemeStrategyScoreDTO.getSchemeId(), dicSingleMap, key);
                } else {
                    //后一个元素不相同则结束循环
                    break;
                }
            }
        }
    }

    /**
     *
     * @author luorui
     * @date 2025/5/23 19:48
     * @discription 对侧线路负载率最低
     * @param list 排序好的集合
     * @param result 收集数据的集合
     * @param dicSingleMap 字典表集合
     * @param key 比较的指标编码
     **/
    private void sortOppositeLineMaxLoadRate(List<FhzgPlanTransferSchemeStrategyScoreDTO> list, Map<Long, List<DicSingle>> result, Map<String, DicSingle> dicSingleMap, String key) {
        if (list.size() > 0) {
            //list已经排序好了 处理可能并列的情况
            FhzgPlanTransferSchemeStrategyScoreDTO fhzgPlanTransferSchemeStrategyScoreDTO_0 = list.get(0);
            Integer oppositeLineMaxLoadRate = fhzgPlanTransferSchemeStrategyScoreDTO_0.getOppositeLineMaxLoadRate();
            for (FhzgPlanTransferSchemeStrategyScoreDTO fhzgPlanTransferSchemeStrategyScoreDTO : list) {
                if (ObjectUtil.equal(fhzgPlanTransferSchemeStrategyScoreDTO.getOppositeLineMaxLoadRate(), oppositeLineMaxLoadRate)) {
                    addTag(result, fhzgPlanTransferSchemeStrategyScoreDTO.getSchemeId(), dicSingleMap, key);
                } else {
                    //后一个元素不相同则结束循环
                    break;
                }
            }
        }
    }


    /**
     *
     * @author luorui
     * @date 2025/5/23 19:48
     * @discription 开关次数最少
     * @param list 排序好的集合
     * @param result 收集数据的集合
     * @param dicSingleMap 字典表集合
     * @param key 比较的指标编码
     **/
    private void sortSwitchOperationTimes(List<FhzgPlanTransferSchemeStrategyScoreDTO> list, Map<Long, List<DicSingle>> result, Map<String, DicSingle> dicSingleMap, String key) {
        if (list.size() > 0) {
            //list已经排序好了 处理可能并列的情况
            FhzgPlanTransferSchemeStrategyScoreDTO fhzgPlanTransferSchemeStrategyScoreDTO_0 = list.get(0);
            Integer switchOperationTimes = fhzgPlanTransferSchemeStrategyScoreDTO_0.getSwitchOperationTimes();
            for (FhzgPlanTransferSchemeStrategyScoreDTO fhzgPlanTransferSchemeStrategyScoreDTO : list) {
                if (ObjectUtil.equal(fhzgPlanTransferSchemeStrategyScoreDTO.getSwitchOperationTimes(), switchOperationTimes)) {
                    addTag(result, fhzgPlanTransferSchemeStrategyScoreDTO.getSchemeId(), dicSingleMap, key);
                } else {
                    //后一个元素不相同则结束循环
                    break;
                }
            }
        }
    }


    /**
     * @author luorui
     * @date 2025/5/23 19:44
     * @discription 将方案id 的对应检查项放入集合
     **/
    private void addTag( Map<Long, List<DicSingle>> result, Long schemeId , Map<String, DicSingle> dicSingleMap, String key) {
        if (null == result.get(schemeId)) {
            List<DicSingle> singleList = new ArrayList<>();
            DicSingle dicSingle = dicSingleMap.get(key);
            singleList.add(dicSingle);
            result.put(schemeId, singleList);
        } else {
            List<DicSingle> singleList = result.get(schemeId);
            DicSingle dicSingle = dicSingleMap.get(key);
            singleList.add(dicSingle);
        }
    }


    /**
     * @author luorui
     * @date 2025/5/23 15:58
     * @discription 转换策略表头
     **/
    private List<EvaluationHeadDTO> caseStrategyConfig(List<FhzgPlanTransferStrategyConfigDetail>  strategyConfigList) {
        List<EvaluationHeadDTO> evaluationHeadDTOList = new ArrayList<>();
        if(CollUtil.isNotEmpty(strategyConfigList)){
            strategyConfigList.forEach(e -> {
                EvaluationHeadDTO evaluationHeadDTO = new EvaluationHeadDTO();
                evaluationHeadDTO.setCode(e.getIndicatorCode());
                evaluationHeadDTO.setSort(e.getPriority());
                evaluationHeadDTO.setName(e.getIndicatorName());
                evaluationHeadDTO.setIsStrategy(TransferSchemeConstants.YesOrNo.YES);
                evaluationHeadDTOList.add(evaluationHeadDTO);
            });
        }
        return evaluationHeadDTOList;
    }
}
