package com.hdkj.lt.mq.service.fault.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.hdkj.lt.base.constants.CommonConstant;
import com.hdkj.lt.base.constants.RedisKeyConstants;
import com.hdkj.lt.base.constants.RocketMQConstants;
import com.hdkj.lt.base.exception.BusinessException;
import com.hdkj.lt.core.bizms.modle.dto.StateEstimation;
import com.hdkj.lt.core.bizms.modle.po.fault.FaultDistMappingFile;
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.sys.dao.FhzgDistMappingFileMapper;
import com.hdkj.lt.core.sys.model.dto.FhzgDistMappingFileDTO;
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.mq.entity.dto.AcceptFaultPowerCutDTO;
import com.hdkj.lt.mq.entity.dto.FeederInfo;
import com.hdkj.lt.mq.entity.po.FhzgFaultPowerCut;
import com.hdkj.lt.mq.service.fault.AcceptFaultPowerCutService;
import com.hdkj.lt.mq.service.fault.IFaultPowerCutService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author luorui
 * @date 2025/5/26 11:16
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class AcceptFaultPowerCutServiceImpl implements AcceptFaultPowerCutService {

    @Autowired
    IFaultPowerCutService faultPowerCutService;
    @Autowired
    RocketMQProperties rocketMQProperties;
    @Autowired
    RocketMQTemplate rocketMQTemplate;
    @Autowired
    ISysStruService sysStruService;

    private final FaultDistMappingFileServiceImpl faultDistMappingFileService;

    private final FhzgDistMappingFileMapper fhzgDistMappingFileMapper;

    @Autowired
    IStateEstimationApiClient iStateEstimationApiClient;

    /**
     * @author luorui
     * @date 2025/5/26 11:16
     * @discription 模拟计划数据，入库，发送MQ消息通知开始解析开关段信息
     **/
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public Boolean acceptFaultPowerCut(AcceptFaultPowerCutDTO acceptFaultPowerCutDTO) {
        //todo 必填字段校验
        List<FhzgFaultPowerCut> result = getFaultByFaultNo(acceptFaultPowerCutDTO.getFaultNo());
        if (CollUtil.isNotEmpty(result) && !"负荷转供".equals(acceptFaultPowerCutDTO.getSourceSystem())) {
            throw new BusinessException("已存在重复的faultNo:" + acceptFaultPowerCutDTO.getFaultNo());
        }
        FhzgFaultPowerCut fhzgFaultPowerCut = new FhzgFaultPowerCut();
        //生成主键
        Snowflake snowflake = IdUtil.getSnowflake(1,1);
        Long faultId = snowflake.nextId();
        fhzgFaultPowerCut.setId(faultId);
        //设置属性字段
        String jsonTxt = JSON.toJSONString(acceptFaultPowerCutDTO);
        fhzgFaultPowerCut.setFeederListJson(jsonTxt);
        fhzgFaultPowerCut.setFaultNo(acceptFaultPowerCutDTO.getFaultNo());
        fhzgFaultPowerCut.setSchemeState("02");//未选定
        fhzgFaultPowerCut.setFaultStartTime(acceptFaultPowerCutDTO.getStartTime());
        fhzgFaultPowerCut.setFaultEndTime(acceptFaultPowerCutDTO.getEndTime());
        fhzgFaultPowerCut.setFaultType(1);
        fhzgFaultPowerCut.setFaultDescription(acceptFaultPowerCutDTO.getFaultDesc());
        fhzgFaultPowerCut.setFaultSource(acceptFaultPowerCutDTO.getSourceSystem());
        List<FeederInfo> feederInfoList = acceptFaultPowerCutDTO.getFeederList();//馈线信息应该只有一条
        if (CollUtil.isNotEmpty(feederInfoList)) {
            fhzgFaultPowerCut.setFeederName(acceptFaultPowerCutDTO.getFeederList().get(0).getFeederName());
            fhzgFaultPowerCut.setLineId(acceptFaultPowerCutDTO.getFeederList().get(0).getFeederPsrId());
            fhzgFaultPowerCut.setLineName(acceptFaultPowerCutDTO.getFeederList().get(0).getFeederName());
        }
        if (null != fhzgFaultPowerCut.getLineId()) {
            List<OrgInfoDto> orgInfoList = sysStruService.getCountyByPsrId(fhzgFaultPowerCut.getLineId());
            if (CollUtil.isNotEmpty(orgInfoList)) {
                fhzgFaultPowerCut.setCountyName(orgInfoList.get(0).getOrganName());
                fhzgFaultPowerCut.setCountyCode(Long.parseLong(orgInfoList.get(0).getStruId()));
            }
        }
        StateEstimation ss = new StateEstimation();
        //保存计划接入时开关pqui数据
        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(Arrays.asList(CommonConstant.SWITCH))
                    .startTime(time)
                    .endTime(time)
                    .isAuto(Boolean.FALSE)
                    .build()).getData(); // 先删除数据
            if (ss != null) {
                fhzgFaultPowerCut.setFeederSwitchInfo(JSON.toJSONString(ss));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        fhzgFaultPowerCut.setCreateTime(LocalDateTime.now());
        fhzgFaultPowerCut.setCreator(8L);
        fhzgFaultPowerCut.setFeederSwitchInfo(JSON.toJSONString(ss));
        faultPowerCutService.save(fhzgFaultPowerCut);
        log.info("保存计划数据成功faultId:{}", faultId);
//        saveFaultFile(fhzgFaultPowerCut.getLineId(), faultId);
        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("2") // 1-计划停电，2-故障停电
                        .body(faultId).build();
                rocketMQTemplate.sendAsyncMessage(messageEntity);
                log.info("发送停电计划解析消息成功faultId{}", faultId);
            }
        } catch (Exception e) {
            //todo 消息发送重试
            log.error("数据落库成功，发送解析计划数据消息失败方案编码faultId:{}", faultId);
        }
        return true;
    }

    private void saveFaultFile(String lineId, Long faultId) {
        if (StrUtil.isBlank(lineId)) {
            throw new BusinessException("馈线编码为空");
        }
        List<String> idList = new ArrayList<>();
        idList.add(lineId);
        List<FhzgDistMappingFileDTO> fhzgDistMappingFileDTOS = fhzgDistMappingFileMapper.getMappingFileById(idList);
        List<FaultDistMappingFile> fileList = new ArrayList<>();
        if (CollUtil.isNotEmpty(fhzgDistMappingFileDTOS)) {
            fhzgDistMappingFileDTOS.forEach(e -> {
                FaultDistMappingFile planDistMappingFile = FaultDistMappingFile.builder()
                        .faultId(faultId)
                        .fileType(e.getFileType())
                        .fileId(e.getFileId())
                        .lineId(e.getLineId())
                        .createTime(LocalDateTime.now())
                        .delFlag("0").build();
                fileList.add(planDistMappingFile);
            });
        }
        if (CollUtil.isNotEmpty(fileList)) {
            faultDistMappingFileService.saveBatch(fileList);
            log.info("保存计划线路图信息完成planId:{},lineId:{}", faultId, lineId);
        }

    }

    private List<FhzgFaultPowerCut> getFaultByFaultNo(String faultNo) {
        Map<String, Object> columnMap = new HashMap<>();
        columnMap.put("fault_no", faultNo);
        List<FhzgFaultPowerCut> list = faultPowerCutService.getBaseMapper().selectByMap(columnMap);
        return list;
    }
}
