package com.sw.mes.receiver;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sw.mes.core.dto.MessageDto;
import com.sw.mes.core.dto.mes.pc.yb.YbInspectDataDto;

import com.sw.mes.core.utils.BeanUtil;
import com.sw.mes.core.utils.StringUtils;
import com.sw.mes.config.RabbitCommon;
import com.sw.mes.domain.ProductionExceptionLog;
import com.sw.mes.gread.common.EnumValuesGrade;
import com.sw.mes.gread.dto.CalculationResultDto;
import com.sw.mes.gread.dto.CalculationResultIfDto;
import com.sw.mes.gread.entity.FieldPool;
import com.sw.mes.gread.entity.GradeRule;
import com.sw.mes.gread.entity.GradeVersion;
import com.sw.mes.gread.service.FieldPoolService;
import com.sw.mes.gread.service.GradeRuleService;
import com.sw.mes.gread.service.GradeVersionService;
import com.sw.mes.core.entity.FbCheckOutData;
import com.sw.mes.service.ProductionExceptionLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.*;

@Slf4j
@Component
public class InspectDataReceiver {
    @Autowired
    private GradeVersionService gradeVersionService;
    @Autowired
    private GradeRuleService gradeRuleService;
    @Autowired
    private FieldPoolService fieldPoolService;
    @Autowired
    private ProductionExceptionLogService productionExceptionLogService;

    @RabbitHandler
    @RabbitListener(queues = RabbitCommon.INSPECT_DATA_QUEUE)
    public void handleInspectDataQueue(String messageStr, Message message, Channel channel) {
        MessageProperties messageProperties = message.getMessageProperties();
        if (messageProperties != null && StringUtils.isNotBlank(messageProperties.getCorrelationId())) {
            log.error("接收到圆棒检验数据【" + messageProperties.getCorrelationId() + "】：" + messageStr);
        }
        try {
            GradeVersion gradeVersion = gradeVersionService.findTopByStatusAndRegion(EnumValuesGrade.GradeVersionStatus.已生效.getKey(), EnumValuesGrade.Region.圆棒报警.getKey());
            if (gradeVersion == null) {
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
                return;
            }
            MessageDto messageDto = JSONObject.parseObject(messageStr, MessageDto.class);
            YbInspectDataDto inspectDataBaseDto = JSONObject.parseObject(messageDto.getContent(), YbInspectDataDto.class);
            Map<String, Object> inspectMap = BeanUtil.convertObjectToMap(inspectDataBaseDto, YbInspectDataDto.class);
            exceException(inspectDataBaseDto.getSectionNo(), inspectDataBaseDto.getDopant(), inspectDataBaseDto.getProductTypeSecond(),
                    inspectMap, gradeVersion, EnumValuesGrade.Region.圆棒.getKey(), messageDto.getUserCreate());

            channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @RabbitHandler
    @RabbitListener(queues = RabbitCommon.FB_INSPECT_DATA_QUEUE)
    public void handleFbInspectDataQueue(String messageStr, Message message, Channel channel) {
        MessageProperties messageProperties = message.getMessageProperties();
        if (messageProperties != null && StringUtils.isNotBlank(messageProperties.getCorrelationId())) {
            log.error("接收到方棒检验数据【" + messageProperties.getCorrelationId() + "】：" + messageStr);
        }
        try {
            GradeVersion gradeVersion = gradeVersionService.findTopByStatusAndRegion(EnumValuesGrade.GradeVersionStatus.已生效.getKey(), EnumValuesGrade.Region.方棒报警.getKey());
            if (gradeVersion == null) {
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
                return;
            }
            MessageDto messageDto = JSONObject.parseObject(messageStr, MessageDto.class);
            FbCheckOutData checkOutData = JSONObject.parseObject(messageDto.getContent(), FbCheckOutData.class);
            Map<String, Object> inspectMap = BeanUtil.convertObjectToMap(checkOutData, FbCheckOutData.class);
            exceException(checkOutData.getFbSectionNo(), checkOutData.getDopant(), checkOutData.getSpecification(),
                    inspectMap, gradeVersion, EnumValuesGrade.Region.方棒.getKey(), messageDto.getUserCreate());
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 异常报警处理
     *
     * @param sectionNo      晶段编号
     * @param dopant         掺杂剂
     * @param specification  规格
     * @param inspectDataMap 检验数据
     * @param gradeVersion   规则版本
     * @param region         字段池区域
     * @param userCreate
     */
    @Async
    public void exceException(String sectionNo, String dopant, String specification, Map<String, Object> inspectDataMap,
                              GradeVersion gradeVersion, int region, String userCreate) {
        if (inspectDataMap == null || inspectDataMap.size() == 0) {
            return;
        }
        // 普通规则
        List<GradeRule> gradeRules = gradeRuleService.findByGradeVersionIdAndGradeTypeIdNotOrderByPriority(gradeVersion.getId(), 0L);
        List<FieldPool> fieldPools = fieldPoolService.findByRegion(region);
        Map<String, FieldPool> fieldPoolMap = new HashMap<>();
        for (FieldPool fieldPool : fieldPools) {
            fieldPoolMap.put(fieldPool.getName(), fieldPool);
        }
        if (StringUtils.isBlank(dopant)) {
            return;
        }
        if (StringUtils.isBlank(specification)) {
            return;
        }
        gradeRules = gradeRuleService.getRradeRulesData(gradeRules, dopant, specification);
        // 没有评级规则
        if (gradeRules.size() == 0) {
            log.error(sectionNo + "：版本【" + gradeVersion.getVersion() + "】中，掺杂剂【" + dopant + "】" + "规格【" + specification + "】没有评级规则");
            return;
        }
        Map<String, CalculationResultDto> combinedField = new HashMap<>();
        List<CalculationResultIfDto> calculationResultIfDtos = refreshGrade(inspectDataMap, gradeRules, fieldPoolMap, combinedField);
        List<ProductionExceptionLog> exceptionLogOlds = productionExceptionLogService.findBySectionNoAndStatus(sectionNo, false);
        Map<String, ProductionExceptionLog> exceptionLogOldMap = new HashMap<>();
        for (ProductionExceptionLog exceptionLogOld : exceptionLogOlds) {
            exceptionLogOldMap.put(exceptionLogOld.getExceptionName(), exceptionLogOld);
        }
        List<ProductionExceptionLog> exceptionLogs = new ArrayList<>();
        ProductionExceptionLog exceptionLog = new ProductionExceptionLog();
        for (CalculationResultIfDto calculationResultIfDto : calculationResultIfDtos) {
            String exceptionName = calculationResultIfDto.getGrade() + "-" + calculationResultIfDto.getIndex();
            if (exceptionLogOldMap.containsKey(exceptionName)) {
                exceptionLog.setId(exceptionLogOldMap.get(exceptionName).getId());
            }
            exceptionLog.setType(region);
            exceptionLog.setSectionNo(sectionNo);
            exceptionLog.setExceptionName(exceptionName);
            exceptionLog.setConditions(JSON.toJSONString(calculationResultIfDto));
            exceptionLog.setStatus(false);
            exceptionLog.setProcessInfo(null);
            exceptionLog.setUserCreate(userCreate);
            exceptionLog.setUserUpdate(null);
            exceptionLog.setGmtCreate(new Date());
            exceptionLog.setGmtUpdate(null);
            exceptionLogs.add(exceptionLog);
        }
        productionExceptionLogService.saveBatch(exceptionLogs);
        log.info(JSON.toJSONString(calculationResultIfDtos));
    }


    /**
     * @param inspectMap
     * @param gradeRules
     * @param fieldPoolMap
     * @param combinedField
     */
    public List<CalculationResultIfDto> refreshGrade(Map<String, Object> inspectMap, List<GradeRule> gradeRules, Map<String, FieldPool> fieldPoolMap, Map<String, CalculationResultDto> combinedField) {
        // 计算评级
        List<CalculationResultIfDto> calculationResultIfDtos = new ArrayList<>();
        for (GradeRule gradeRule : gradeRules) {
            String[] conditionsArr = gradeRule.getConditions() == null ? new String[]{} : gradeRule.getConditions().split("\\[OR\\]");
            int index1 = 0;
            for (String conditions : conditionsArr) {
                if (conditions != null) {
                    index1++;
                    CalculationResultIfDto result = fieldPoolService.exceGrade(conditions, inspectMap, fieldPoolMap, combinedField);
                    result.setGrade(gradeRule.getGrade());
                    result.setIndex(Integer.toString(index1));
                    System.out.println(inspectMap.get("section_no") + "-评级过程，评级状态：" + (result.getResultType() ? "成功；" : "失败；") + "评级结果：" + (result.getResult() == null || result.getResult() ? "成功" : "失败") + "评级名称【" + gradeRule.getName() + "】评级过程：" + JSON.toJSONString(result));
                    //计算成功
                    if (result.getResultType()) {
                        //满足该条件
                        if (result.getResult() != null && result.getResult()) {
                            //保存异常记录
                            calculationResultIfDtos.add(result);
                        }
                    } else { //评级失败，不继续评级
                        log.error("该条件判断出错");
                    }
                }
            }
        }
        return calculationResultIfDtos;
    }
}
