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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hdkj.lt.feign.IFaultCreateClient;
import com.hdkj.lt.modle.dto.fault.RegenerateFaultRequest;
import com.hdkj.lt.base.exception.BusinessException;
import com.hdkj.lt.bf.entity.dto.HasDataTagDTO;
import com.hdkj.lt.bf.entity.vo.FhzgFaultPowerCutSectionVO;
import com.hdkj.lt.bf.entity.vo.FhzgFaultPowerCutVO;
import com.hdkj.lt.bf.mapper.FaultAwaitTransferUsersMapper;
import com.hdkj.lt.bf.mapper.FaultDistMappingFileMapper;
import com.hdkj.lt.bf.mapper.FaultPowerCutMapper;
import com.hdkj.lt.bf.mapper.FhzgFaultSwitchInfoListMapper;
import com.hdkj.lt.bf.service.*;
import com.hdkj.lt.bf.service.aspect.UserCountyCodeAuto;
import com.hdkj.lt.core.bizms.modle.dto.FhzgFaultAwaitTransferUsersCountDTO;
import com.hdkj.lt.core.bizms.modle.dto.FhzgFaultDistCustomerDTO;
import com.hdkj.lt.core.bizms.modle.dto.FhzgFaultDistMappingFileDTO;
import com.hdkj.lt.core.bizms.modle.po.fault.*;
import com.hdkj.lt.modle.dto.jsty.AllSwitchInfoListDTO;
import com.ruoyi.common.core.utils.StringUtils;
import io.jsonwebtoken.lang.Assert;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * <p>
 * 故障停电转供信息表 服务实现类
 * </p>
 *
 * @author luorui
 * @since 2025-05-29
 */
@Service
@Slf4j
public class FaultPowerCutServiceImpl extends ServiceImpl<FaultPowerCutMapper, FaultPowerCut> implements IFaultPowerCutService {

    @Autowired
    FaultDistMappingFileMapper faultDistMappingFileMapper;

    @Autowired
    FaultAwaitTransferUsersMapper faultAwaitTransferUsersMapper;

    @Autowired
    IFaultPowerCutPvUsersService faultPowerCutPvUsersService;

    @Autowired
    IFaultAwaitTransferSwitchSectionService awaitTransferSwitchSectionServices;

    @Autowired
    IFaultOppositeLineCarryCapacityService oppositeLineCarryCapacityService;

    @Autowired
    IFaultTransferSchemeService faultTransferSchemeService;
    @Autowired
    FhzgFaultSwitchInfoListMapper switchInfoListMapper;
    @Autowired
    private IFaultPowerCutSwitchService faultPowerCutSwitchService;

    @Autowired
    IFaultCreateClient faultCreateClient;

    @Override
    @UserCountyCodeAuto(sourceFiled = "countyCode", targetFiled = "countyCodeList")
    public Page<FhzgFaultPowerCutVO> getSchemeList(FaultPowerCut obj) {
        Page<FhzgFaultPowerCutVO> page = new Page<>();
        page.setCurrent(obj.getPageNum());
        page.setSize(obj.getPageSize());
//        List<FhzgFaultPowerCutVO> list = baseMapper.selectSchemeList(page, obj);
        List<FhzgFaultPowerCutVO> list = baseMapper.selectSchemeList2(page, obj);

        if (CollUtil.isNotEmpty(list)) {
            //获取故障停电主键id，grid_pd_outage_event_base.id
            List<String> faultNoList = list.stream().map(FhzgFaultPowerCutVO::getFaultId).collect(Collectors.toList());
            //根据faultId获取idList,fhzg_fault_power_cut.id
            List<FaultPowerCut> faultList = this.list(new LambdaQueryWrapper<FaultPowerCut>().in(FaultPowerCut::getFaultNo, faultNoList));
            List<Long> idList = faultList.stream().map(FaultPowerCut::getId).collect(Collectors.toList());
            //获取开关信息
            List<FhzgFaultPowerCutSectionVO> faultPowerCutSectionList = switchInfoListMapper.querySectionsSwitchByFaultId(idList);
            Map<String, List<FhzgFaultPowerCutSectionVO>> sectionMap = faultPowerCutSectionList.stream().collect(Collectors.groupingBy(
                    FhzgFaultPowerCutSectionVO::getFaultNo,
                    Collectors.collectingAndThen(
                            Collectors.toList(),
                            ls -> ls.stream().sorted(
                                            Comparator.comparing(FhzgFaultPowerCutSectionVO::getSectionStatus, Comparator.reverseOrder())
                                                    .thenComparing(FhzgFaultPowerCutSectionVO::getCreateTime, Comparator.reverseOrder()))
                                    .collect(Collectors.toList())))
            );
            //查询计划对应的线路图信息
            List<FhzgFaultDistMappingFileDTO> fileList = faultDistMappingFileMapper.getMappingFileByPlanId(idList);
            if (CollUtil.isNotEmpty(faultPowerCutSectionList)) {
                Map<Long, List<FhzgFaultDistMappingFileDTO>> fileListMap = fileList.stream().collect(Collectors.groupingBy(FhzgFaultDistMappingFileDTO::getFaultId));
                list.forEach(e -> {
                    Long id = e.getId();
                    Optional.of(fileListMap).ifPresent(p -> e.setFileList(Objects.nonNull(p.get(id)) ? p.get(id) : Lists.newArrayList()));
                    //故障id
                    String fId = e.getFaultId();
                    List<FhzgFaultPowerCutSectionVO> faultPowerCuts = null != sectionMap.get(fId) ? sectionMap.get(fId) : new ArrayList<>();
                    faultPowerCuts.forEach(section -> Optional.of(fileListMap).ifPresent(f -> section.setFileList(Objects.nonNull(f.get(section.getFaultId())) ? f.get(section.getFaultId()) : Lists.newArrayList())));
                    e.setSectionList(faultPowerCuts);
                });
            } else {
                log.info("未查询到故障停电开关信息faultIdList:{}", idList);
            }
            //查询统计，用户数量，重要用户数量，敏感用户数量，用户负荷
            List<FhzgFaultAwaitTransferUsersCountDTO> usersCountDTOList = faultAwaitTransferUsersMapper.selectAwaitUserCountByFaultId(idList);
            //查询停电计划对应的光伏用户数量
            List<FaultPowerCutPvUsers> countCutPvUsers = faultPowerCutPvUsersService.countByFaultId(idList);
            Map<Long, FhzgFaultAwaitTransferUsersCountDTO> fusersCountMap = usersCountDTOList.stream().collect(Collectors.toMap(FhzgFaultAwaitTransferUsersCountDTO::getFaultId, Function.identity(), (k1, k2) -> k2));
            Map<Long, FaultPowerCutPvUsers> cutPvUsersMap = countCutPvUsers.stream().collect(Collectors.toMap(FaultPowerCutPvUsers::getFaultId, Function.identity(), (k1, k2) -> k2));
            BigDecimal multiplyNumber = new BigDecimal("1000");
            list.forEach(e -> {
                Long id = e.getId();
                FhzgFaultAwaitTransferUsersCountDTO userCountDtoDefault = fusersCountMap.get(id);
                FaultPowerCutPvUsers faultPowerCutPvUsersDefault = cutPvUsersMap.get(id);
                fillUserCountInfo(userCountDtoDefault, faultPowerCutPvUsersDefault, e, null, multiplyNumber);
                List<FhzgFaultPowerCutSectionVO> sectionList = e.getSectionList();
                sectionList.forEach(section -> {
                    Long faultId = section.getFaultId();
                    FhzgFaultAwaitTransferUsersCountDTO userCountDTO = fusersCountMap.get(faultId);
                    FaultPowerCutPvUsers faultPowerCutPvUsers = cutPvUsersMap.get(faultId);
                    fillUserCountInfo(userCountDTO, faultPowerCutPvUsers, e, section, multiplyNumber);
                });
            });
        } else {
            log.info("查询故障停电数据为空condition:{}", obj);
        }
        return page.setRecords(list);
    }

    /**
     * 填充用户数量信息
     */
    private void fillUserCountInfo(FhzgFaultAwaitTransferUsersCountDTO userCountDto, FaultPowerCutPvUsers powerCutPvUsers,
                                   FhzgFaultPowerCutVO vo, FhzgFaultPowerCutSectionVO sectionVO,
                                   BigDecimal multiplyNumber) {
        Integer pvCount = Objects.isNull(powerCutPvUsers) ? 0 : Objects.isNull(powerCutPvUsers.getCount()) ? 0 : powerCutPvUsers.getCount();
        if (Objects.isNull(sectionVO)) {
            vo.setPvUsers(pvCount);
            if (Objects.nonNull(userCountDto)) {
                //重要用户数量
                vo.setTransferCriticalUsers(userCountDto.getTransferCriticalUsers());
                //敏感用户
                vo.setTransferSensitiveUsers(userCountDto.getTransferSensitiveUsers());
                //用户数量
                vo.setUserCount(userCountDto.getUserCount());
                //用户负荷,空则0
                vo.setUserLoads(Objects.isNull(userCountDto.getUserLoads())
                        ? BigDecimal.ZERO : userCountDto.getUserLoads().multiply(multiplyNumber));
                //保电用户数量
                vo.setProtectUsers(userCountDto.getProtectUsers());
            }
        } else {
            sectionVO.setPvUsers(pvCount);
            if (Objects.nonNull(userCountDto)) {
                //重要用户数量
                sectionVO.setTransferCriticalUsers(userCountDto.getTransferCriticalUsers());
                //敏感用户
                sectionVO.setTransferSensitiveUsers(userCountDto.getTransferSensitiveUsers());
                //用户数量
                sectionVO.setUserCount(userCountDto.getUserCount());
                //用户负荷,空则0
                sectionVO.setUserLoads(Objects.isNull(userCountDto.getUserLoads())
                        ? BigDecimal.ZERO : userCountDto.getUserLoads().multiply(multiplyNumber));
                //保电用户数量
                sectionVO.setProtectUsers(userCountDto.getProtectUsers());
            }
        }

    }

    @Override
    public HasDataTagDTO getHasDataTag(FhzgFaultDistCustomerDTO dto) {
        Long faultId = dto.getFaultId();
        if (Objects.isNull(faultId)) {
            throw new BusinessException("查询参数planId为空");
        }
        HasDataTagDTO hasDataTagDTO = new HasDataTagDTO();
        Boolean transferAreaTag = false;
        Boolean transferSchemeTag = false;
        Boolean transferScoreTag = false;
        //查询转供范围下是否有数据，待转供用户，待转供开关段，对侧承载力分析 都没有数据则为false
        LambdaQueryWrapper<FaultAwaitTransferUsers> awaitTransferUsersWrapper = new LambdaQueryWrapper<>();
        awaitTransferUsersWrapper.eq(FaultAwaitTransferUsers::getFaultId, faultId);
        Long countAwaitTransferUsers = faultAwaitTransferUsersMapper.selectCount(awaitTransferUsersWrapper);
        if (countAwaitTransferUsers != null && countAwaitTransferUsers.compareTo(0L) > 0) {
            transferAreaTag = true;
        }
        if (!transferAreaTag) {
            LambdaQueryWrapper<FaultAwaitTransferSwitchSection> awaitTransferSwitchWrapper = new LambdaQueryWrapper<>();
            awaitTransferSwitchWrapper.eq(FaultAwaitTransferSwitchSection::getFaultId, faultId);
            Long countAwaitTransferSwitch = awaitTransferSwitchSectionServices.count(awaitTransferSwitchWrapper);
            if (countAwaitTransferSwitch != null && countAwaitTransferSwitch.compareTo(0L) > 0) {
                transferAreaTag = true;
            }
        }
        if (!transferAreaTag) {
            LambdaQueryWrapper<FaultOppositeLineCarryCapacity> oppositeLineCarryWrapper = new LambdaQueryWrapper<>();
            oppositeLineCarryWrapper.eq(FaultOppositeLineCarryCapacity::getFaultId, faultId);
            Long countOppositeLineCarry = oppositeLineCarryCapacityService.count(oppositeLineCarryWrapper);
            if (countOppositeLineCarry != null && countOppositeLineCarry.compareTo(0L) > 0) {
                transferAreaTag = true;
            }
        }
        //查询转供方案是否有数据  转供方案是否有数据   //查询转供方案评分是否有数据 评分指标结果 和 评分细则都没数据则不显示
        LambdaQueryWrapper<FaultTransferScheme> schemeWrapper = new LambdaQueryWrapper<>();
        schemeWrapper.eq(FaultTransferScheme::getFaultId, faultId);
        Long countScheme = faultTransferSchemeService.count(schemeWrapper);
        if (countScheme != null && countScheme.compareTo(0L) > 0) {
            transferSchemeTag = true;
            transferScoreTag = true;
        }
        hasDataTagDTO.setTransferAreaTag(transferAreaTag);
        hasDataTagDTO.setTransferSchemeTag(transferSchemeTag);
        hasDataTagDTO.setTransferScoreTag(transferScoreTag);
        log.info("返回前端标识,transferAreaTag:{},transferSchemeTag:{},:transferScoreTag:{}", transferAreaTag, transferSchemeTag, transferScoreTag);
        return hasDataTagDTO;
    }

    @Override
    public Integer updateSchemeState(FaultPowerCut obj) {
        if (Objects.isNull(obj.getId())) {
            throw new BusinessException("更新方案主键为空");
        }
        if (StrUtil.isBlank(obj.getSchemeState())) {
            throw new BusinessException("更新方案字段为空");
        }
        return baseMapper.updateSchemeState(obj);
    }

    @Override
    public FhzgFaultPowerCutVO getSchemeByFaultId(Long faultId) {
        FhzgFaultPowerCutVO faultPowerCutVO = baseMapper.getSchemeByFaultId(faultId);
        return faultPowerCutVO;
    }

    @Override
    public List<AllSwitchInfoListDTO> getAllSwitchBySchemeId(Long faultId) {
        LambdaQueryWrapper<FhzgFaultSwitchInfoList> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(FhzgFaultSwitchInfoList::getFaultId, faultId);
        FhzgFaultSwitchInfoList switchInfoList = switchInfoListMapper.selectOne(lambdaQueryWrapper);
        //  FaultPowerCut faultPowerCut = baseMapper.selectById(faultId);
        String allSwitchInfoListJson = switchInfoList.getAllSwitchInfoListJson();
        return JSON.parseArray(allSwitchInfoListJson, AllSwitchInfoListDTO.class);
    }

    @Override
    @Transactional(rollbackFor = BusinessException.class)
    public void updateSectionStatus(Long faultId) {
        FaultPowerCut entity = this.getById(faultId);
        Assert.notNull(entity, "故障区段信息不存在");
        List<FaultPowerCut> list = this.list(new LambdaQueryWrapper<FaultPowerCut>().eq(FaultPowerCut::getFaultNo, entity.getFaultNo()));
        list.forEach(e -> {
            Integer sectionStatus = Objects.equals(faultId, e.getId()) ? 1 : 0;
            e.setSectionStatus(sectionStatus);
        });
        this.updateBatchById(list);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public void deleteSection(Long faultId) {
        FaultPowerCut entity = this.getById(faultId);
        Assert.notNull(entity, "故障区段信息不存在");
        this.removeById(faultId);
        //删除开关
        faultPowerCutSwitchService.remove(new LambdaQueryWrapper<FaultPowerCutSwitch>().eq(FaultPowerCutSwitch::getFaultId, faultId));
    }

    @Override
    public void regenerateFault(RegenerateFaultRequest request) {
        faultCreateClient.regenerateFault(request);
    }
}
