package com.hdkj.lt.mq.service.plan.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.lang.generator.SnowflakeGenerator;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hdkj.lt.core.bizms.modle.po.plan.FhzgPlanAwaitTransferUsers;
import com.hdkj.lt.core.bizms.modle.po.plan.FhzgPlanTransferScheme;
import com.hdkj.lt.core.bizms.modle.po.plan.PlanAwaitTransferAreaResultPO;
import com.hdkj.lt.modle.dto.jsty.*;
import com.hdkj.lt.mq.mapper.plan.FhzgPlanAnalyzeCalculateDecudeMapper;
import com.hdkj.lt.mq.mapper.plan.PlanAwaitTransferAreaResultMapper;
import com.hdkj.lt.mq.service.plan.AnalysisPlanTransferSchemeService;
import com.hdkj.lt.mq.service.plan.IPlanTransferSchemeService;
import com.hdkj.lt.utils.math.DecimalUtils;
import com.hdkj.lt.utils.security.StrConvertUtils;
import com.hdkj.hussar.ApiResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @author luorui
 * @date 2025/5/24 17:28
 * 解析计算推演平台数据并落库业务表
 */
@Service
@Slf4j
public class AnalysisPlanTransferSchemeServiceImpl implements AnalysisPlanTransferSchemeService {

    @Autowired
    IPlanTransferSchemeService fhzgPlanTransferSchemeService;

    @Autowired
    PlanAwaitTransferAreaResultMapper awaitTransferAreaResultMapper;

    @Autowired
    FhzgPlanAnalyzeCalculateDecudeMapper fhzgPlanAnalyzeCalculateDecudeMapper;

    /**
     * @author luorui
     * @date 2025/5/24 18:07
     * @discription 解析大对象终的转供方案落库
     **/
    public void analysisPlanTransferScheme(Long planId, Map<Long, XferPlanDTO> xferPlanMap, List<FhzgPlanAwaitTransferUsers> awaitTransferUsers) {
        // 生成方案前需要覆盖方案相关级联数据
        //fhzgPlanAnalyzeCalculateDecudeMapper.deleteTransferSchemeAndLinkInfoByPlanId(planId);
        deleteTransferSchemeAndLinkInfoByPlanId(planId);
        //返回保存的主键和 计划的对象
//        Map<Long,XferPlanDTO> idXferPlanDTOMap = new HashMap<>();
        List<FhzgPlanTransferScheme> fhzgPlanTransferSchemeList = new ArrayList<>();
        for (Long schemeId : xferPlanMap.keySet()) {
            XferPlanDTO xferPlanDTO = xferPlanMap.get(schemeId);
            List<List<BreakerInfoDTO>> breakerOperationOrderList = xferPlanDTO.getBreakerOperationOrderListList();//开关动作顺序数据
            Integer switchOperationCount = null;
            if (CollUtil.isNotEmpty(breakerOperationOrderList)) {
                for (List<BreakerInfoDTO> list : breakerOperationOrderList) {
                    if (CollUtil.isNotEmpty(list)) {
                        switchOperationCount = (switchOperationCount == null) ? list.size() : list.size() + switchOperationCount;
                    }
                }
            }
            List<XferSupplyAreaDTO> xferSupplyAreaList = xferPlanDTO.getXferSupplyAreaList(); // 转供方案开关及设备区域信息

            FhzgPlanTransferScheme fhzgPlanTransferScheme = new FhzgPlanTransferScheme();
            fhzgPlanTransferScheme.setPlanId(planId);//计划编码

            fhzgPlanTransferScheme.setSchemeState("02");//方案选择状态默认 "02" 未选定
            fhzgPlanTransferScheme.setSwitchOperationCount(switchOperationCount);//开关动作次数(计算推演平台breakerOperationInfo动作开关计数)
            this.setCountValue(fhzgPlanTransferScheme, xferSupplyAreaList, awaitTransferUsers);
            fhzgPlanTransferScheme.setCreateTime(LocalDateTime.now());
            fhzgPlanTransferScheme.setId(schemeId);
            fhzgPlanTransferScheme.setRowJson(JSON.toJSONString(xferPlanMap.get(schemeId)));
//            idXferPlanDTOMap.put(fhzgPlanTransferScheme.getId(),xferPlanDTO);

            fhzgPlanTransferSchemeList.add(fhzgPlanTransferScheme);
        }
        // 根据最大负载率 升序 取前十
        AtomicInteger index = new AtomicInteger(1);
        List<FhzgPlanTransferScheme> transferSchemesList = fhzgPlanTransferSchemeList.stream()
                .sorted(Comparator.comparing(FhzgPlanTransferScheme::getPlanMaxCurrentLoad))
                .map(e -> e.setSchemeName(String.format("方案%s", StrConvertUtils.toChineseStr(index.getAndIncrement()))))//方案编码
                .limit(10).collect(Collectors.toList());
        // fhzgPlanTransferScheme.setSchemeName("方案" + StrConvertUtils.toChineseStr(index));//方案编码
        fhzgPlanTransferSchemeService.saveBatch(transferSchemesList);
    }

    /**
     * @author luorui
     * @date 2025/5/25 11:03
     * @discription 测试解析转供计划数据
     **/
    @Override
    public Map<Long, XferPlanDTO> analysis(Long planId) {
        PlanAwaitTransferAreaResultPO po = getTransferAreaResultByPlanId(planId);
        if (po != null) {
            ApiResponse response = JSON.parseObject(po.getTransferAreaJson(), ApiResponse.class);
            response.getData();
            ApiDataDTO data = JSON.parseObject(JSON.toJSONString(response.getData()), ApiDataDTO.class);
            Snowflake snowflake = IdUtil.getSnowflake(1, 1);
            //将待转供区域的用户 负荷收集起来
            List<FhzgPlanAwaitTransferUsers> dataList = new ArrayList<>();
            List<SupplyAreaDTO> supplyAreaList = data.getSupplyAreaList();
            supplyAreaList.forEach(e -> {
                Optional.ofNullable(e.getAreaDevice()).ifPresent(en -> {
                    if (ObjectUtils.isNotEmpty(en.getMvTransList())) {
                        en.getMvTransList().forEach(device -> {
                            FhzgPlanAwaitTransferUsers awaitTransferUser = new FhzgPlanAwaitTransferUsers();
                            awaitTransferUser.setTransformerNo(device.getPsrID())
                                    .setTransformerName(device.getName())
                                    .setDeviceType(device.getPsrType())
                                    .setUserLoads(this.getMetricValue(device.getP()))
                                    .setPlanId(planId).setCreateTime(LocalDateTime.now());
                            dataList.add(awaitTransferUser);
                        });
                    }
                    if (ObjectUtils.isNotEmpty(en.getMvCustomerList())) {
                        en.getMvCustomerList().forEach(device -> {
                            FhzgPlanAwaitTransferUsers awaitTransferUser = new FhzgPlanAwaitTransferUsers();
                            awaitTransferUser.setTransformerNo(device.getPsrID())
                                    .setTransformerName(device.getName())
                                    .setUserLoads(this.getMetricValue(device.getP()))
                                    .setPlanId(planId).setCreateTime(LocalDateTime.now());

                            dataList.add(awaitTransferUser);
                        });
                    }
                });
            });
            Map<Long, XferPlanDTO> result = data.getXferPlanList()
                    .stream().collect(Collectors.toMap(e -> snowflake.nextId(), e -> e));
            this.analysisPlanTransferScheme(planId, result, dataList);
            log.info("解析数据生成方案数据完成planId:{}", planId);
            return result;
        }
        return null;
    }

    private BigDecimal getMetricValue(MetricValueDTO device) {
        return Optional.ofNullable(device)
                .filter(d -> ObjectUtils.allNotNull(d, d.getValue()))
                .map(d -> BigDecimal.valueOf(d.getValue()))
                .orElse(null);
    }

    public PlanAwaitTransferAreaResultPO getTransferAreaResultByPlanId(@NotNull Long planId) {
        LambdaQueryWrapper<PlanAwaitTransferAreaResultPO> queryWrapper = new LambdaQueryWrapper<PlanAwaitTransferAreaResultPO>()
                .eq(PlanAwaitTransferAreaResultPO::getPlanId, planId).last(" limit 1");
        return awaitTransferAreaResultMapper.selectOne(queryWrapper);
    }

    //转供方案的子区域,设置统计字段
    private void setCountValue(FhzgPlanTransferScheme fhzgPlanTransferScheme, List<XferSupplyAreaDTO> xferSupplyAreaList, List<FhzgPlanAwaitTransferUsers> awaitTransferUsers) {
        Integer lossUser = null;//损失用户，为不可转供区域的 中压用户和公变用户的数量之和
        //如果没有不可转供区域则 lossUser 为 0
        //计算是否为推荐方案
        boolean schemeCheck = true; //只要有一个区域的 对侧负荷大于80%则不是推荐方案

        //收集可转供 中压用户和公变用户 psrId集合 ,从待转供用户中筛选出 对应用户，累计转供前的用户负荷
        List<String> userList = new ArrayList<>();
        for (XferSupplyAreaDTO dto : xferSupplyAreaList) {
            //不可转区域用户信息,损失户数
            AreaDeviceDTO areaDeviceInfo = dto.getAreaDeviceInfo();
            if (!Objects.equals(dto.getPowerOnSuccess(), Boolean.TRUE)) {
                if (areaDeviceInfo != null) {
                    //如果推演平台数据有问题，有不可转供区域但是 公变和中压信息为 null
                    Integer countMvTransList = CollUtil.isEmpty(areaDeviceInfo.getMvTransList()) ? null : areaDeviceInfo.getMvTransList().size();
                    Integer countMvCustomerList = CollUtil.isEmpty(areaDeviceInfo.getMvCustomerList()) ? null : areaDeviceInfo.getMvCustomerList().size();
                    if (countMvTransList != null || countMvCustomerList != null) {
                        lossUser = (countMvTransList == null ? 0 : countMvTransList) + (countMvCustomerList == null ? 0 : countMvCustomerList);
                    }
                }
            } else {
                //可转供区域用户信息,中压用户和公变用户  中压光伏列表
                if (areaDeviceInfo != null) {
                    // 公变信息列表
                    List<TransCustomerDTO> mvTransList = areaDeviceInfo.getMvTransList();
                    if (CollUtil.isNotEmpty(mvTransList)) {
                        List<String> psrIdList = mvTransList.stream().filter(e -> StrUtil.isNotBlank(e.getPsrID())).map(TransCustomerDTO::getPsrID).collect(Collectors.toList());
                        userList.addAll(psrIdList);
                    }
                    // 中压用户列表
                    List<TransCustomerDTO> mvCustomerList = areaDeviceInfo.getMvCustomerList();
                    if (CollUtil.isNotEmpty(mvCustomerList)) {
                        List<String> psrIdList = mvCustomerList.stream().filter(e -> StrUtil.isNotBlank(e.getPsrID())).map(TransCustomerDTO::getPsrID).collect(Collectors.toList());
                        userList.addAll(psrIdList);
                    }
                }
            }
            Double planMaxCurrentLoad = dto.getLinkLineInfo().getPlanMaxCurrentLoad();//线路出来最大负载（%）
            // 设置最大负载率，用来筛选升序前十条数据, 当值为空时确保排序靠后
            fhzgPlanTransferScheme.setPlanMaxCurrentLoad(Optional.ofNullable(planMaxCurrentLoad).map(BigDecimal::valueOf).orElse(BigDecimal.valueOf(200.0)));
            if (planMaxCurrentLoad != null && planMaxCurrentLoad > 80) {
                //todo  对方传值为空怎么处理
                schemeCheck = false;
            }
        }
        //方案中的不可转供区域如果没有的话 损失户数为 0
        Long nonArea = xferSupplyAreaList.stream().filter(e -> !Objects.equals(e.getPowerOnSuccess(), Boolean.TRUE)).count();
        if (Objects.equals(nonArea, 0L)) {
            lossUser = 0;//前面可能为空
        }
        //从待转供用户中筛选出来可转供的用户 用来计算可转供负荷和 转供总负荷
        double userTransferSum = awaitTransferUsers.stream()
                .filter(en -> userList.contains(en.getTransformerNo()) && ObjectUtils.isNotEmpty(en.getUserLoads()))
                .map(en -> en.getUserLoads()).mapToDouble(BigDecimal::doubleValue).sum();
        BigDecimal userTransferSumBigDecimal = BigDecimal.valueOf(userTransferSum).setScale(6, RoundingMode.HALF_UP);
        double totalTransferSum = awaitTransferUsers.stream()
                .filter(en -> ObjectUtils.isNotEmpty(en.getUserLoads()))
                .map(en -> en.getUserLoads()).mapToDouble(BigDecimal::doubleValue).sum();
        BigDecimal totalTransferSumBigDecimal = BigDecimal.valueOf(totalTransferSum).setScale(6, RoundingMode.HALF_UP);

        fhzgPlanTransferScheme.setFeasibleTransfer(userTransferSumBigDecimal);//可行的转供负荷数
        fhzgPlanTransferScheme.setTotalTransfer(totalTransferSumBigDecimal);//转供总负荷数
        fhzgPlanTransferScheme.setLoadRecovery((DecimalUtils.divide(totalTransferSumBigDecimal, userTransferSumBigDecimal, 4, RoundingMode.HALF_UP)).multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP));//负荷恢复
        fhzgPlanTransferScheme.setLossCustHours(lossUser == null ? null : new BigDecimal(lossUser)); //损失时户
        fhzgPlanTransferScheme.setLossUsers(lossUser); //损失时户

        fhzgPlanTransferScheme.setSchemeCheck(schemeCheck ? "1" : "0");//scheme_check	方案校验结果(1-通过，0-不通过)
    }

    /**
     * 删除所有方案相关表数据
     *
     * @param planId
     */
    public void deleteTransferSchemeAndLinkInfoByPlanId(Long planId) {
        // 先删依赖 switching 的
        fhzgPlanAnalyzeCalculateDecudeMapper.deleteSwitchingLoopCheckByPlanId(planId);
        fhzgPlanAnalyzeCalculateDecudeMapper.deleteSwitchingFinalCheckByPlanId(planId);
        fhzgPlanAnalyzeCalculateDecudeMapper.deleteLoopSwCurrentDetailByPlanId(planId);
        fhzgPlanAnalyzeCalculateDecudeMapper.deleteLoopSegCurrentDetailByPlanId(planId);
        fhzgPlanAnalyzeCalculateDecudeMapper.deleteFinalSwCurrentDetailByPlanId(planId);
        fhzgPlanAnalyzeCalculateDecudeMapper.deleteFinalSegCurrentDetailByPlanId(planId);

        // 再删 switching_sequence
        fhzgPlanAnalyzeCalculateDecudeMapper.deleteSwitchingSequenceByPlanId(planId);

        // 删除其他关联表
        fhzgPlanAnalyzeCalculateDecudeMapper.deleteBreakerSvgAfterByPlanId(planId);
        fhzgPlanAnalyzeCalculateDecudeMapper.deletePathDetailByPlanId(planId);
        fhzgPlanAnalyzeCalculateDecudeMapper.deleteOppositeLineLoadFactorByPlanId(planId);
        fhzgPlanAnalyzeCalculateDecudeMapper.deleteSchemeUsersByPlanId(planId);
        fhzgPlanAnalyzeCalculateDecudeMapper.deleteTransferableSchemeUsersByPlanId(planId);
        fhzgPlanAnalyzeCalculateDecudeMapper.deleteOppositeLineConcatSwitchByPlanId(planId);
        fhzgPlanAnalyzeCalculateDecudeMapper.deleteEvaluationIndexByPlanId(planId);
        fhzgPlanAnalyzeCalculateDecudeMapper.deleteStrategyScoreByPlanId(planId);

        // 删除直接按 plan_id 关联的
        fhzgPlanAnalyzeCalculateDecudeMapper.deleteCarryCapacityByPlanId(planId);
        fhzgPlanAnalyzeCalculateDecudeMapper.deleteAwaitTransferUsersByPlanId(planId);

        // 最后删主表
        fhzgPlanAnalyzeCalculateDecudeMapper.deleteTransferSchemeByPlanId(planId);

    }

}
