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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hdkj.lt.base.constants.CommonConstant;
import com.hdkj.lt.base.constants.RedisKeyConstants;
import com.hdkj.lt.base.constants.RocketMQConstants;
import com.hdkj.lt.core.bizms.modle.dto.StateEstimation;
import com.hdkj.lt.core.bizms.modle.po.FeederTopo;
import com.hdkj.lt.core.bizms.modle.request.StateEstimationRequest;
import com.hdkj.lt.core.mq.client.RocketMQTemplate;
import com.hdkj.lt.core.mq.config.RocketMQProperties;
import com.hdkj.lt.core.mq.model.RocketMQMessageEntity;
import com.hdkj.lt.core.plugins.thread.MultiThreadExecuteService;
import com.hdkj.lt.core.sys.dao.FhzgDistMappingFileMapper;
import com.hdkj.lt.core.sys.model.dto.OrgInfoDto;
import com.hdkj.lt.core.sys.service.ISysStruService;
import com.hdkj.lt.feign.IStateEstimationApiClient;
import com.hdkj.lt.modle.dto.plan.PlanCreateSwitchDTO;
import com.hdkj.lt.mq.entity.dto.AcceptPlanPowerCutDTO;
import com.hdkj.lt.mq.entity.dto.AcceptPlanPowerCutListDTO;
import com.hdkj.lt.mq.entity.dto.BreakerInfo;
import com.hdkj.lt.mq.entity.dto.FeederInfo;
import com.hdkj.lt.mq.entity.po.FhzgPlanPowerCut;
import com.hdkj.lt.mq.mapper.base.FeederTopoMapper;
import com.hdkj.lt.mq.mapper.plan.PlanPowerCutMapper;
import com.hdkj.lt.mq.service.plan.AcceptPlanPowerCutService;
import com.hdkj.lt.mq.service.plan.FhzgReasoningPlatformService;
import com.hdkj.lt.mq.service.plan.IPlanDistMappingFileService;
import com.hdkj.lt.mq.service.plan.IPlanPowerCutService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * @author luorui
 * @date 2025/5/26 11:16
 */
@Service
@Slf4j
public class AcceptPlanPowerCutServiceImpl implements AcceptPlanPowerCutService {


    @Autowired
    IPlanPowerCutService planPowerCutService;
    @Autowired
    RocketMQProperties rocketMQProperties;
    @Autowired
    RocketMQTemplate rocketMQTemplate;
    @Autowired
    ISysStruService sysStruService;
    @Autowired
    FhzgDistMappingFileMapper fhzgDistMappingFileMapper;
    @Autowired
    IPlanDistMappingFileService planDistMappingFileService;
    @Autowired
    IStateEstimationApiClient iStateEstimationApiClient;
    @Autowired
    FeederTopoMapper feederTopoMapper;
    @Autowired
    PlanPowerCutMapper powerCutMapper;
    @Autowired
    FhzgReasoningPlatformService platformService;
    @Autowired
    MultiThreadExecuteService multiThreadExecuteService;

    /**
     * @author luorui
     * @date 2025/5/26 11:16
     * @discription 模拟计划数据，入库，发送MQ消息通知开始解析开关段信息
     **/
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public Boolean acceptPlanPowerCut(AcceptPlanPowerCutDTO acceptPlanPowerCutDTO) {
        //todo 必填字段校验
        List<FhzgPlanPowerCut> result = getPlanByPlanNo(acceptPlanPowerCutDTO.getPlanNo());
        FhzgPlanPowerCut fhzgPlanPowerCut = new FhzgPlanPowerCut();
//        //生成主键
//        Long planId;
//        if (CollUtil.isNotEmpty(result)) {
////            throw new BusinessException("已存在重复的planNo:" + acceptPlanPowerCutDTO.getPlanNo());
//            planId = result.get(0).getId();
//            fhzgPlanPowerCut.setId(planId);
//        } else {
//            SnowflakeGenerator idGenerator = new SnowflakeGenerator();
//            planId = idGenerator.next();
//            fhzgPlanPowerCut.setId(planId);
//        }
        //把最新标识（plan_no分组内，1-是，0-不是）设置为0
        List<FhzgPlanPowerCut> updatePlanPowerCutList = result.stream()
                .map(e -> FhzgPlanPowerCut.builder().isNewest("0").id(e.getId()).build())
                .collect(Collectors.toList());
        planPowerCutService.updateBatchById(updatePlanPowerCutList);
        Long planId = acceptPlanPowerCutDTO.getPlanId();
        fhzgPlanPowerCut.setId(planId);
        //设置属性字段
        String jsonTxt = JSON.toJSONString(acceptPlanPowerCutDTO);
        fhzgPlanPowerCut.setFeederListJson(jsonTxt);
        fhzgPlanPowerCut.setPlanNo(acceptPlanPowerCutDTO.getPlanNo());
        fhzgPlanPowerCut.setPlanState(acceptPlanPowerCutDTO.getPlanStatus());
        fhzgPlanPowerCut.setSchemeState("02");//未选定
        fhzgPlanPowerCut.setPlanStartTime(acceptPlanPowerCutDTO.getStartTime());
        fhzgPlanPowerCut.setPlanEndTime(acceptPlanPowerCutDTO.getEndTime());
        fhzgPlanPowerCut.setWorkContent(acceptPlanPowerCutDTO.getPlanDesc());
        fhzgPlanPowerCut.setPlanSource(acceptPlanPowerCutDTO.getSourceSystem());
        fhzgPlanPowerCut.setValidFlag(acceptPlanPowerCutDTO.getValidFlag());
        fhzgPlanPowerCut.setPowerOnSuccess(2);//2标识计划方案生成中
        fhzgPlanPowerCut.setIsNewest("1");//最新标识设置为1
        //判断计划是否删除
        if ("delete".equals(acceptPlanPowerCutDTO.getValidFlag())) {
            fhzgPlanPowerCut.setIsDelete(1);
        } else {
            fhzgPlanPowerCut.setIsDelete(0);
        }
        List<FeederInfo> feederInfoList = acceptPlanPowerCutDTO.getFeederList();//馈线信息应该只有一条
        if (CollUtil.isNotEmpty(feederInfoList)) {
            fhzgPlanPowerCut.setFeederName(acceptPlanPowerCutDTO.getFeederList().get(0).getFeederName());
            fhzgPlanPowerCut.setLineId(acceptPlanPowerCutDTO.getFeederList().get(0).getFeederPsrId());
            fhzgPlanPowerCut.setLineName(acceptPlanPowerCutDTO.getFeederList().get(0).getFeederName());
        }
        if (null != fhzgPlanPowerCut.getLineId()) {
            List<OrgInfoDto> orgInfoList = sysStruService.getCountyByPsrId(fhzgPlanPowerCut.getLineId());
            if (CollUtil.isNotEmpty(orgInfoList)) {
                fhzgPlanPowerCut.setCountyName(orgInfoList.get(0).getOrganName());
                fhzgPlanPowerCut.setCountyCode(Long.parseLong(orgInfoList.get(0).getStruId()));
            }
        }
        fhzgPlanPowerCut.setCreateTime(LocalDateTime.now());
        fhzgPlanPowerCut.setCreator(8L);
        StateEstimation ss = new StateEstimation();
        try {
            LocalDateTime now = LocalDateTime.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            String time = now.format(formatter);
            ss = iStateEstimationApiClient.queryByFeederSave(StateEstimationRequest.builder()
                    .psrIds(Collections.singletonList(feederInfoList.get(0).getFeederPsrId()))
                    .containerCode(Collections.singletonList(CommonConstant.SWITCH))
                    .startTime(time)
                    .endTime(time)
                    .build()).getData(); // 先删除数据
            if (ss != null) {
                fhzgPlanPowerCut.setFeederSwitchInfo(JSON.toJSONString(ss));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        planPowerCutService.saveOrUpdate(fhzgPlanPowerCut);
        log.info("保存计划数据成功planId:{}", planId);
        try {
            if (rocketMQProperties.getEnabled()) {
                RocketMQMessageEntity messageEntity = RocketMQMessageEntity.builder()
                        .topicId(RocketMQConstants.TOPIC_ID_POWER_CUT_RESULT_TICKET)
                        .cacheKey(RedisKeyConstants.ASYNC_POWER_CUT_RESULT_TOPIC_TICKET)
                        .tag("1") // 1-计划停电，2-故障停电
                        .body(planId).build();
                rocketMQTemplate.sendAsyncMessage(messageEntity);
                log.info("发送停电计划解析消息成功planId{}", planId);
            }
        } catch (Exception e) {
            //todo 消息发送重试
            log.error("数据落库成功，发送解析计划数据消息失败方案编码planId:{}", planId);
        }
        return true;
    }


    /**
     * @author luorui
     * @date 2025/5/26 11:16
     * @discription 模拟计划数据，入库，发送MQ消息通知开始解析开关段信息
     **/
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public Boolean acceptPlanPowerCutLocal(AcceptPlanPowerCutDTO acceptPlanPowerCutDTO) {
        //todo 必填字段校验
        List<FhzgPlanPowerCut> result = getPlanByPlanNo(acceptPlanPowerCutDTO.getPlanNo());
        FhzgPlanPowerCut fhzgPlanPowerCut = new FhzgPlanPowerCut();
        //生成主键
        Long planId;
        if (CollUtil.isNotEmpty(result)) {
//            throw new BusinessException("已存在重复的planNo:" + acceptPlanPowerCutDTO.getPlanNo());
            planId = result.get(0).getId();
            fhzgPlanPowerCut.setId(planId);
        } else {
            Snowflake snowflake = IdUtil.getSnowflake(1,1);
            planId = snowflake.nextId();
            fhzgPlanPowerCut.setId(planId);
        }
        List<FhzgPlanPowerCut> updatePlanPowerCutList = result.stream()
                .map(e -> FhzgPlanPowerCut.builder().isNewest("0").id(e.getId()).build())
                .collect(Collectors.toList());
        planPowerCutService.updateBatchById(updatePlanPowerCutList);
        fhzgPlanPowerCut.setId(planId);
        //设置属性字段
        String jsonTxt = JSON.toJSONString(acceptPlanPowerCutDTO);
        fhzgPlanPowerCut.setFeederListJson(jsonTxt);
        fhzgPlanPowerCut.setPlanNo(acceptPlanPowerCutDTO.getPlanNo());
        fhzgPlanPowerCut.setPlanState(acceptPlanPowerCutDTO.getPlanStatus());
        fhzgPlanPowerCut.setSchemeState("02");//未选定
        fhzgPlanPowerCut.setPlanStartTime(acceptPlanPowerCutDTO.getStartTime());
        fhzgPlanPowerCut.setPlanEndTime(acceptPlanPowerCutDTO.getEndTime());
        fhzgPlanPowerCut.setWorkContent(acceptPlanPowerCutDTO.getPlanDesc());
        fhzgPlanPowerCut.setPlanSource(acceptPlanPowerCutDTO.getSourceSystem());
        fhzgPlanPowerCut.setValidFlag(acceptPlanPowerCutDTO.getValidFlag());
        fhzgPlanPowerCut.setIsNewest("1");//最新标识设置为1
        //判断计划是否删除
        if ("delete".equals(acceptPlanPowerCutDTO.getValidFlag())) {
            fhzgPlanPowerCut.setIsDelete(1);
        } else {
            fhzgPlanPowerCut.setIsDelete(0);
        }
        List<FeederInfo> feederInfoList = acceptPlanPowerCutDTO.getFeederList();//馈线信息应该只有一条
        if (CollUtil.isNotEmpty(feederInfoList)) {
            fhzgPlanPowerCut.setFeederName(acceptPlanPowerCutDTO.getFeederList().get(0).getFeederName());
            fhzgPlanPowerCut.setLineId(acceptPlanPowerCutDTO.getFeederList().get(0).getFeederPsrId());
            fhzgPlanPowerCut.setLineName(acceptPlanPowerCutDTO.getFeederList().get(0).getFeederName());
        }
        if (null != fhzgPlanPowerCut.getLineId()) {
            List<OrgInfoDto> orgInfoList = sysStruService.getCountyByPsrId(fhzgPlanPowerCut.getLineId());
            if (CollUtil.isNotEmpty(orgInfoList)) {
                fhzgPlanPowerCut.setCountyName(orgInfoList.get(0).getOrganName());
                fhzgPlanPowerCut.setCountyCode(Long.parseLong(orgInfoList.get(0).getStruId()));
            }
        }
        fhzgPlanPowerCut.setCreateTime(LocalDateTime.now());
        fhzgPlanPowerCut.setCreator(8L);
        planPowerCutService.save(fhzgPlanPowerCut);
        log.info("保存计划数据成功planId:{}", planId);
        try {
            if (rocketMQProperties.getEnabled()) {
                RocketMQMessageEntity messageEntity = RocketMQMessageEntity.builder()
                        .topicId(RocketMQConstants.TOPIC_ID_POWER_CUT_RESULT_TICKET)
                        .cacheKey(RedisKeyConstants.ASYNC_POWER_CUT_RESULT_TOPIC_TICKET)
                        .tag("1") // 1-计划停电，2-故障停电
                        .body(planId).build();
                rocketMQTemplate.sendAsyncMessage(messageEntity);
                log.info("发送停电计划解析消息成功planId{}", planId);
            }
        } catch (Exception e) {
            //todo 消息发送重试
            log.error("数据落库成功，发送解析计划数据消息失败方案编码planId:{}", planId);
        }
        return true;
    }


    /**
     * 批量生成计划（编号,id,状态均采用默认值，计划选取出线开关停电）
     *
     * @param
     */
    @Override
    public boolean acceptPlanPowerCutList(AcceptPlanPowerCutListDTO dto) {
        Snowflake snowflake = IdUtil.getSnowflake(1,1);
        dto.getFeederList().forEach(
                e -> {
                    Long planId = snowflake.nextId();
                    String planNo = String.valueOf(snowflake.nextId());
                    FeederInfo feederInfo = new FeederInfo();
                    FeederTopo feederTopo = feederTopoMapper.getFeederInfoById(e);
                    feederInfo.setFeederPsrId(e);
                    feederInfo.setFeederName(feederTopo.getFeederName());
                    AcceptPlanPowerCutDTO planPowerCutDTO = AcceptPlanPowerCutDTO.builder()
                            .feederList(new ArrayList<>(Collections.singletonList(feederInfo)))
                            .planNo("JHTD" + planNo)
                            .planId(planId)
                            .planDesc("线路id:" + e + "整线停电")
                            .validFlag("valid")
                            .sourceSystem("02")
                            .startTime(dto.getStartTime())
                            .endTime(dto.getEndTime())
                            .build();
//                    try {
//                        Thread.sleep(60000);
//                    } catch (InterruptedException ex) {
//                        throw new RuntimeException(ex);
//                    }
                    // acceptPlanPowerCut(planPowerCutDTO);
                    CompletableFuture.runAsync(() -> acceptPlanPowerCut(planPowerCutDTO), multiThreadExecuteService.getExecutor());
                }
        );
        return true;
    }

    public String autoTaskCreatePlan(AcceptPlanPowerCutListDTO dto) {
        log.info(dto.toString());
        Long planId = IdUtil.getSnowflakeNextId();
        String planNo = String.valueOf(planId);
        FeederInfo feederInfo = new FeederInfo();
        FeederTopo feederTopo = feederTopoMapper.getFeederInfoById(dto.getFeederList().get(0));
        feederInfo.setFeederPsrId(dto.getFeederList().get(0));
        feederInfo.setFeederName(feederTopo.getFeederName());
        AcceptPlanPowerCutDTO planPowerCutDTO = AcceptPlanPowerCutDTO.builder()
                .feederList(new ArrayList<>(Collections.singletonList(feederInfo)))
                .planNo("JHTD" + planNo)
                .planId(planId)
                .planDesc("线路id:" + dto.getFeederList().get(0) + "整线停电")
                .validFlag("valid")
                .sourceSystem("02")
                .startTime(dto.getStartTime())
                .endTime(dto.getEndTime())
                .build();
        acceptPlanPowerCut(planPowerCutDTO);
        return planNo;
    }

    /**
     * 重试时间范围内所有没有成功生成方案的计划
     *
     * @param dto
     * @return
     */
    public boolean reTryPlanPowerCutList(AcceptPlanPowerCutListDTO dto) {
        LambdaQueryWrapper<FhzgPlanPowerCut> wrapper = new LambdaQueryWrapper<>();
//        wrapper.between(FhzgPlanPowerCut::getCreateTime, dto.getStartTime(), dto.getEndTime());
        wrapper.isNull(FhzgPlanPowerCut::getPowerOnSuccess);
        List<FhzgPlanPowerCut> list = powerCutMapper.selectList(wrapper);
        list.forEach(e -> {
            CompletableFuture.runAsync(() -> platformService.getPowerOutAreaList(e.getId()), multiThreadExecuteService.getExecutor());
        });
        return true;
    }


    private List<FhzgPlanPowerCut> getPlanByPlanNo(String planNo) {
        Map<String, Object> columnMap = new HashMap<>();
        columnMap.put("plan_no", planNo);
        List<FhzgPlanPowerCut> list = planPowerCutService.getBaseMapper().selectByMap(columnMap);
        return list;
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    @Override
    public boolean createPlanPowerCut(PlanCreateSwitchDTO planCreateSwitchDTO) {
        Snowflake snowflake = IdUtil.getSnowflake(1,1);
        List<FeederInfo> feederInfoList = new ArrayList<>();
        FeederInfo feederInfo = new FeederInfo();
        feederInfo.setFeederPsrId(planCreateSwitchDTO.getFeederId());
        feederInfo.setFeederName(planCreateSwitchDTO.getFeederName());
        List<BreakerInfo> breakerInfoList = new ArrayList<>();
        if(StringUtils.isNotBlank(planCreateSwitchDTO.getStartSwitchId())){
            List<BreakerInfo> breakerInfo = feederTopoMapper.getSwitchInfoByPsrID(planCreateSwitchDTO.getStartSwitchId());
            breakerInfoList.addAll(breakerInfo);
        }
        if(StringUtils.isNotBlank(planCreateSwitchDTO.getEndSwitchID())){
            List<BreakerInfo> endBreakerInfo = feederTopoMapper.getSwitchInfoByPsrID(planCreateSwitchDTO.getEndSwitchID());
            breakerInfoList.addAll(endBreakerInfo);
        }
        feederInfo.setBreakerList(breakerInfoList);
        feederInfoList.add(feederInfo);
        Long next = snowflake.nextId();
        AcceptPlanPowerCutDTO acceptPlanPowerCutDTO = AcceptPlanPowerCutDTO.builder()
                .startTime(planCreateSwitchDTO.getStartTime())
                .endTime(planCreateSwitchDTO.getEndTime())
                .sourceSystem("02")
                .planDesc(planCreateSwitchDTO.getWorkContent())
                .feederList(feederInfoList)
                .planId(next)
                .planNo("JHTD" + next).build();
        return acceptPlanPowerCut(acceptPlanPowerCutDTO);
    }
}
