package com.hdkj.lt.mq.listener;

import cn.hutool.core.date.DatePattern;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.openservices.ons.api.Action;
import com.aliyun.openservices.ons.api.ConsumeContext;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.MessageListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hdkj.lt.base.constants.RedisKeyConstants;
import com.hdkj.lt.base.constants.RocketMQConstants;
import com.hdkj.lt.base.enums.CommonUnitEnum;
import com.hdkj.lt.base.exception.ExceptionCast;
import com.hdkj.lt.core.bizms.modle.po.MessageRetryLog;
import com.hdkj.lt.core.bizms.modle.po.operationAbnormality.FhzgGridOperationAbnormality;
import com.hdkj.lt.core.bizms.modle.po.plan.PlanAwaitTransferAreaResultPO;
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.FhzgOrganSuffixMapper;
import com.hdkj.lt.feign.ISimulationPlatformApiClient;
import com.hdkj.lt.modle.dto.simulation.FaultTransferSchemeDTO;
import com.hdkj.lt.modle.dto.simulation.FeederCheckRule;
import com.hdkj.lt.modle.dto.simulation.OperationSchemeDTO;
import com.hdkj.lt.modle.dto.simulation.PlanTransferSchemeDTO;
import com.hdkj.lt.mq.entity.dto.DeviceTypeDto;
import com.hdkj.lt.mq.entity.po.FaultPowerCutSwitchPO;
import com.hdkj.lt.mq.entity.po.FhzgFaultPowerCut;
import com.hdkj.lt.mq.entity.po.FhzgPlanPowerCut;
import com.hdkj.lt.mq.entity.po.PlanPowerCutSwitchPO;
import com.hdkj.lt.mq.mapper.base.FeederTopoMapper;
import com.hdkj.lt.mq.mapper.plan.PlanAwaitTransferAreaResultMapper;
import com.hdkj.lt.mq.service.abnormal.impl.FhzgGridOperationAbnormalityServiceImpl;
import com.hdkj.lt.mq.service.base.MessageRetryLogService;
import com.hdkj.lt.mq.service.fault.FaultPowerCutSwitchService;
import com.hdkj.lt.mq.service.fault.IFaultPowerCutService;
import com.hdkj.lt.mq.service.plan.IPlanPowerCutService;
import com.hdkj.lt.mq.service.plan.PlanPowerCutSwitchService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author rj
 * @date 2025/5/25 下午3:18
 * @description
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class RocketConsumerSimulationPlatformListener implements MessageListener {

    private final RocketMQProperties rocketMQProperties;
    private final RocketMQTemplate rocketMQTemplate;
    private final PlanPowerCutSwitchService planPowerCutSwitchService;
    private final ISimulationPlatformApiClient simulationPlatformApiClient;
    private final IPlanPowerCutService iPlanPowerCutService;
    private final FeederTopoMapper feederTopoMapper;
    private final FaultPowerCutSwitchService faultPowerCutSwitchService;
    private final MessageRetryLogService messageRetryLogService;
    private final FhzgOrganSuffixMapper fhzgOrganSuffixMapper;
    private final PlanAwaitTransferAreaResultMapper resultMapper;
    private final FhzgGridOperationAbnormalityServiceImpl operationAbnormalityService;
    private final IFaultPowerCutService faultPowerCutService;


    @Override
    public Action consume(Message message, ConsumeContext consumeContext) {
        try {
            log.info("===== 推演平台计划转供方案-开始消费 =====");
            String type = message.getTag();
            String value = new String(message.getBody(), StandardCharsets.UTF_8);
            Long planId = Long.parseLong(value);
            this.executeFunc(planId, type);

            // 计算完成后需要把计划ID提供, 发送解析转供范围计算计算推演平台结果消息
            if (rocketMQProperties.getEnabled()) {
                RocketMQMessageEntity messageEntity = RocketMQMessageEntity.builder()
                        .topicId(RocketMQConstants.TOPIC_ID_ANALYSIS_TRANSFER_RESULT_TICKET)
                        .cacheKey(RedisKeyConstants.ASYNC_QUEUE_ANALYSIS_TRANSFER_RESULT_TICKET)
                        .tag(type) // 1-计划停电，2-故障停电,3-运行调优，4-全口径低电压
                        .body(planId).build();
                rocketMQTemplate.sendAsyncMessage(messageEntity);
            }
            return Action.CommitMessage;
        } catch (Exception e) {
            MessageRetryLog messageRetryLog = MessageRetryLog.builder().messageId(message.getTopic())
                    .errorLog(e.getMessage()).messageBody(Arrays.toString(message.getBody()))
                    .tag("1").step(3).build();
            messageRetryLogService.saveLog(messageRetryLog);
            e.printStackTrace();
            return Action.ReconsumeLater;
        }
    }

    public void executeFunc(Long planId, String type) {
        if ("1".equals(type)) {
            LambdaQueryWrapper<PlanAwaitTransferAreaResultPO> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(PlanAwaitTransferAreaResultPO::getPlanId, planId);
            PlanAwaitTransferAreaResultPO resultPO = resultMapper.selectOne(wrapper);
            if (resultPO != null) {
                if (resultPO.getTransferAreaJson() != null && !resultPO.getTransferAreaJson().isEmpty()) {
                    return;
                }
            }
            //计划
            //获取参数
            PlanPowerCutSwitchPO planPowerCutSwitchPO = planPowerCutSwitchService.getOne(new LambdaQueryWrapper<PlanPowerCutSwitchPO>().eq(PlanPowerCutSwitchPO::getPlanId, planId));
            FhzgPlanPowerCut fhzgPlanPowerCut = iPlanPowerCutService.getById(planId);
            //获取计划停电转供方案
            PlanTransferSchemeDTO planTransferSchemeDTO = new PlanTransferSchemeDTO();
            planTransferSchemeDTO.setFeederId(fhzgPlanPowerCut.getLineId());
            planTransferSchemeDTO.setStartTime(fhzgPlanPowerCut.getPlanStartTime().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
            planTransferSchemeDTO.setEndTime(fhzgPlanPowerCut.getPlanEndTime().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
            planTransferSchemeDTO.setLoadTransferTime(planTransferSchemeDTO.getStartTime());
            PlanTransferSchemeDTO.StartBreakerDTO startBreakerDTO = new PlanTransferSchemeDTO.StartBreakerDTO();
            startBreakerDTO.setSwitchId(planPowerCutSwitchPO.getStartSwitch());
            //动态切换表名
            //*ztj ArgTableNameHandler.setArgument(fhzgOrganSuffixMapper.getOrganSuffixByPlanIdOrLineId(planId, null));
            List<DeviceTypeDto> deviceType = feederTopoMapper.getDeviceType(Arrays.asList(planPowerCutSwitchPO.getStartSwitch()));
            if (CollectionUtils.isNotEmpty(deviceType)) {
                if (CommonUnitEnum.ONE.getCode().equals(deviceType.get(0).getIsStartKg())) {
                    startBreakerDTO.setDistribution(1);
                } else {
                    startBreakerDTO.setDistribution(0);
                }
                startBreakerDTO.setSwitchType(deviceType.get(0).getDwdPsrType());
            }
            planTransferSchemeDTO.setStartBreaker(startBreakerDTO);
            List<PlanTransferSchemeDTO.StartBreakerDTO> endBreakerList = new ArrayList<>();
            if (StringUtils.isNotEmpty(planPowerCutSwitchPO.getEndSwitch())) {
                String[] split = planPowerCutSwitchPO.getEndSwitch().split(",");
                //动态切换表名
                //*ztj ArgTableNameHandler.setArgument(fhzgOrganSuffixMapper.getOrganSuffixByPlanIdOrLineId(planId, null));
                List<DeviceTypeDto> endDeviceType = feederTopoMapper.getDeviceType(Arrays.asList(split));
                for (DeviceTypeDto deviceTypeDto : endDeviceType) {
                    PlanTransferSchemeDTO.StartBreakerDTO endBreakerDTO = new PlanTransferSchemeDTO.StartBreakerDTO();
                    endBreakerDTO.setSwitchType(deviceTypeDto.getDwdPsrType());
                    endBreakerDTO.setSwitchId(deviceTypeDto.getPsrId());
                    if (CommonUnitEnum.ONE.getCode().equals(deviceTypeDto.getStartKgId())) {
                        endBreakerDTO.setDistribution(1);
                    } else {
                        endBreakerDTO.setDistribution(0);
                    }
                    endBreakerList.add(endBreakerDTO);
                }
            }
            planTransferSchemeDTO.setEndBreakerList(endBreakerList);
            planTransferSchemeDTO.setAbnormalBreakerList(new ArrayList<>());

            planTransferSchemeDTO.setPlanId(planId);
            //动态切换表名
            //*ztj ArgTableNameHandler.setArgument(fhzgOrganSuffixMapper.getOrganSuffixByPlanIdOrLineId(planId, null));
            //获取对侧线路额定电流信息
            List<FeederCheckRule> feederCheckRule = new ArrayList<>();
            //feederTopoMapper.getFeederCheckRule(fhzgPlanPowerCut.getLineId());
            PlanTransferSchemeDTO.LoopCheckRule loopCheckRule = new PlanTransferSchemeDTO.LoopCheckRule();
            loopCheckRule.setFeederLoadRate(80);
            planTransferSchemeDTO.setLoopCheckRule(loopCheckRule);
            planTransferSchemeDTO.setFeederCheckRuleList(feederCheckRule);
            String planTransferScheme = simulationPlatformApiClient.getPlanTransferScheme(planTransferSchemeDTO);

            if (planTransferScheme == null) {
                //方案生成失败状态更新
                fhzgPlanPowerCut.setPowerOnSuccess(3);
                iPlanPowerCutService.updateById(fhzgPlanPowerCut);
                ExceptionCast.cast("计划停电生成方案失败");
            } else {
                log.info("计划停电推演平台调用成功，id:" + planId);
            }
        } else if ("2".equals(type)) {
            FhzgFaultPowerCut fhzgFaultPowerCut = faultPowerCutService.getById(planId);
            FaultPowerCutSwitchPO faultPowerCutSwitch = faultPowerCutSwitchService.getOne(new LambdaQueryWrapper<FaultPowerCutSwitchPO>().eq(FaultPowerCutSwitchPO::getFaultId, planId));
            String faultAnalysis = faultPowerCutSwitch.getAnalysisJson();
            FaultTransferSchemeDTO faultTransferSchemeDTO = new FaultTransferSchemeDTO();
            faultTransferSchemeDTO.setFaultId(planId);
            faultTransferSchemeDTO.setFaultTransferSchemeParam(faultAnalysis);
            String planTransferScheme = simulationPlatformApiClient.getFaultTransferScheme(faultTransferSchemeDTO);
            if (planTransferScheme == null) {
                //方案生成失败状态更新
                fhzgFaultPowerCut.setPowerOnSuccess(3);
                faultPowerCutService.updateById(fhzgFaultPowerCut);
                ExceptionCast.cast("故障停电生成方案失败");
            } else {
                log.info("故障停电推演平台调用成功，id" + planId);
            }
        } else if ("3".equals(type)) {
            FhzgGridOperationAbnormality one = operationAbnormalityService.getOne(new LambdaQueryWrapper<FhzgGridOperationAbnormality>().eq(FhzgGridOperationAbnormality::getId, planId));
            OperationSchemeDTO operationSchemeDTO = new OperationSchemeDTO();
            operationSchemeDTO.setId(one.getEventId());
            operationSchemeDTO.setOaID(planId);
            operationSchemeDTO.setStartTime(one.getAlarmStartTime());
            operationSchemeDTO.setEndTime(one.getAlarmEndTime());
            operationSchemeDTO.setReason(one.getReason());
            List<OperationSchemeDTO.Feeder> feeders = new ArrayList<>();
            OperationSchemeDTO.Feeder feeder = new OperationSchemeDTO.Feeder();
            feeder.setPsr_id(one.getLineId());
            feeder.setPsr_type(one.getPsrType());
            feeders.add(feeder);
            operationSchemeDTO.setFeeder(feeders);
            String operationScheme = simulationPlatformApiClient.getOperationScheme(operationSchemeDTO);
            log.info("推演平台调用结果" + operationScheme);

        } else if ("4".equals(type)) {

            //String operationScheme = simulationPlatformApiClient.getOperationScheme(operationSchemeDTO);
            log.info("推演平台调用结果");

        } else {
            log.error("没有对应的tag:{}", type);
        }

    }

}
