package com.xisc.pm.app.service.strategy.pdrule;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Maps;
import com.xisc.pm.api.dto.PmProContYieldRequestDTO;
import com.xisc.pm.api.dto.QdMatchParamDTO;
import com.xisc.pm.api.dto.RuleParamDTO;
import com.xisc.pm.app.service.strategy.RuleExecStrategyFactory;
import com.xisc.pm.domain.entity.PmPdSlab;
import com.xisc.pm.domain.repository.MmPlateRepository;
import com.xisc.pm.domain.repository.PmPdSlabRepository;
import com.xisc.pm.domain.vo.MmPlateVO;
import com.xisc.pm.infra.client.QdOrderClient;
import com.xisc.pm.infra.constant.RuleSetConstants;
import com.xisc.pm.infra.enums.PdRuleItemType;

import io.choerodon.core.exception.CommonException;
import lombok.extern.slf4j.Slf4j;

/**
 * 实物炉次化学成分与合同匹配 （S01,S03,S05 , P01）
 * 
 * @author jun.zeng
 * 
 */
@Slf4j
@Component
public class ChemicalCompsitionMatchRuleExecStrategy implements RuleExecStrategy {

    @Autowired
    private PmPdSlabRepository pmPdSlabRepository;
    
    @Autowired
    private MmPlateRepository mmPlateRepository ;

    @Autowired
    private QdOrderClient qdOrderClient;
    
    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public void afterPropertiesSet() throws Exception {
        RuleExecStrategyFactory.register(PdRuleItemType.CHEMICAL_COMPOSITION_MATCH, this);
    }

    @Override
    public boolean execRule(RuleParamDTO ruleParam) {
        Map<String, Object> bizData = ruleParam.getBizData();
        String orderNo = (String) bizData.get(RuleSetConstants.ORDER_NO);
        String matType = (String) bizData.get(RuleSetConstants.MAT_DESIGN_KIND);
        Long organizationId = (Long) bizData.get(RuleSetConstants.TENANT_ID);
        List<String> orderNoList = (List<String>) bizData.get(RuleSetConstants.ORDER_NO_SET);
        //规则10校验
        //获取材料号mat_no
        PmProContYieldRequestDTO pmProContYield = (PmProContYieldRequestDTO) bizData.get(RuleSetConstants.CALC_REQUEST);
        if(pmProContYield != null) {
            if ("S".equals(matType) || "B".equals(matType)) {
                PmPdSlab pmPdSlab = pmProContYield.getPmPdSlab();
                if(pmPdSlab == null) {
                    pmPdSlab = this.pmPdSlabRepository.selectByVirtualSlabNo(pmProContYield.getVirtualSlabNo(), pmProContYield.getTenantId());
                    pmProContYield.setPmPdSlab(pmPdSlab);
                }
              //获取余坯的制造命令号PONO
                String pono = null;
                if (Objects.nonNull(pmPdSlab)) {
                    pono = pmPdSlab.getPono();
                } 
                if(StringUtils.isBlank(pono)) {
                    pono = pmProContYield.getPmContFilterRequest().getPono();
                }
                //将余坯的PONO号、输入的合同号order_no、按合同判熔炼成分方式，传给质量模块化学成分比对api，获取判定结果.
                Map<String, String> checkFlag = check(pono, pono, orderNoList, organizationId , true);
                if(!checkFlag.containsKey(orderNo)) {
                    // 如果结果中不含
                    checkFlag = check(pono, pono, orderNoList, organizationId, false);
                } 
                if (checkFlag.containsKey(orderNo) && "不合格".equals(checkFlag.get(orderNo))) {
                    throw new CommonException("材料【"+ pono +"】与合同【"+orderNo+"】的化学成分比对未通过");
                }
                
            } else if ("P".equals(matType)) {
                MmPlateVO mmPlateVO = pmProContYield.getPmContFilterRequest().getMmPlate();
                if(mmPlateVO == null) {
                    mmPlateVO = mmPlateRepository.selectByPrimary(pmProContYield.getPmContFilterRequest().getPlateId());
                    pmProContYield.getPmContFilterRequest().setMmPlate(mmPlateVO);
                }
                if (Objects.nonNull(mmPlateVO)) {
                    //获取余材的制造命令号PONO
                    String pono = mmPlateVO.getPono();
                    //将余材的PONO号、输入的合同号order_no、按合同判熔炼成分方式，传给质量模块化学成分比对api，获取判定结果.
                    Map<String, String> checkFlag = check(mmPlateVO.getMatNo(),pono, orderNoList, organizationId , true);
                    if(!checkFlag.containsKey(orderNo)) {
                        // 如果结果中不含
                        checkFlag = check(mmPlateVO.getMatNo(),pono,  orderNoList, organizationId, false);
                    } 
                    if (checkFlag.containsKey(orderNo) && "不合格".equals(checkFlag.get(orderNo))) {
                        throw new CommonException("材料【"+ mmPlateVO.getMatNo() +"】与合同【"+orderNo+"】的化学成分比对未通过");
                    }
                }
            }
        }
        String pono = (String) bizData.get(RuleSetConstants.PONO);
        if(StringUtils.isNotBlank(pono)) {
            Map<String, String> checkFlag = check(pono, pono, orderNoList, organizationId , true);
            if(!checkFlag.containsKey(orderNo)) {
                // 如果结果中不含
                checkFlag = check(pono, pono, orderNoList, organizationId, false);
            } 
            if (checkFlag.containsKey(orderNo) && "不合格".equals(checkFlag.get(orderNo))) {
                throw new CommonException("材料【"+ pono +"】与合同【"+orderNo+"】的化学成分比对未通过");
            }
        }
        return true;
    }
    
    private Map<String , String> check(String matNo, String pono, List<String> orderNoList, Long organizationId , boolean queryCache) {
        // 未通过校验的列表集合
        Map<String, String> checkFlag = Maps.newHashMap();
        String key = PdRuleItemType.CHEMICAL_COMPOSITION_MATCH.name() + "." + matNo;
        if (!queryCache) {
            if (orderNoList == null || orderNoList.isEmpty()) {
                return Maps.newHashMap();
            }
            List<QdMatchParamDTO> dtoList = new ArrayList<QdMatchParamDTO>(
                    orderNoList.size());
            for (String orderNo : orderNoList) {
                QdMatchParamDTO phyFurnaceChemicalMatchDTO = new QdMatchParamDTO();
                phyFurnaceChemicalMatchDTO.setOrderNo(orderNo);
                phyFurnaceChemicalMatchDTO.setPono(pono);
                dtoList.add(phyFurnaceChemicalMatchDTO);
            }
            List<QdMatchParamDTO> reslut = qdOrderClient.phyFurnaceChemicalMatchApi(organizationId,
                    dtoList);
            if(reslut != null && !reslut.isEmpty()) {
                for (QdMatchParamDTO qdMatchParamDTO : reslut) {
                    checkFlag.put(qdMatchParamDTO.getOrderNo(), qdMatchParamDTO.getResult());
                }
            }
            for (String orderNo : orderNoList) {
                if(!checkFlag.containsKey(orderNo)) {
                    checkFlag.put(orderNo, "合格");
                }
            }
            try {
                CACHE.put(key, objectMapper.writeValueAsString(checkFlag));
            } catch (JsonProcessingException e) {
                log.error(e.getMessage() , e);
            }
            return checkFlag;
        } else {
            try {
                String vuale = CACHE.getIfPresent(key);
                if(StringUtils.isBlank(vuale)) {
                    return Maps.newHashMap();
                }
                checkFlag = objectMapper.readValue(vuale, Map.class);
                return checkFlag;
            } catch (JsonMappingException e) {
                log.error(e.getMessage(), e);
            } catch (JsonProcessingException e) {
                log.error(e.getMessage(), e);
            }
            return Maps.newHashMap();
        }
    }
    
}
