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.Lists;
import com.google.common.collect.Maps;
import com.xisc.pm.api.dto.PmProContYieldRequestDTO;
import com.xisc.pm.api.dto.QdSurplusLowMagnificationDTO;
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.PmPdSlabRepository;
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）
 * 
 * @author jun.zeng
 * 
 * 
 * 
 */
@Slf4j
@Component
public class LowPowerRequirementRuleExecStrategy implements RuleExecStrategy {

    @Autowired
    private QdOrderClient qdOrderClient;

    @Autowired
    private PmPdSlabRepository pmPdSlabRepository;
    
    @Autowired
    private ObjectMapper objectMapper;

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

    @Override
    public boolean execRule(RuleParamDTO ruleParam) {
        Map<String, Object> bizData = ruleParam.getBizData();
        String orderNo = (String) bizData.get(RuleSetConstants.ORDER_NO);
        String mscLineNo = (String) bizData.get(RuleSetConstants.MSC_LINE_NO);
        Long organizationId = (Long) bizData.get(RuleSetConstants.TENANT_ID);
        List<String> orderNoList = (List<String>) bizData.get(RuleSetConstants.ORDER_NO_SET);
        PmProContYieldRequestDTO pmProContYield = (PmProContYieldRequestDTO) bizData.get(RuleSetConstants.CALC_REQUEST);
        if(pmProContYield != null) {
            // C05时会传入收得率计算参数
            PmPdSlab pmPdSlab = pmProContYield.getPmPdSlab();
            if (pmPdSlab == null) {
                pmPdSlab = this.pmPdSlabRepository.selectByVirtualSlabNo(pmProContYield.getVirtualSlabNo(),
                        pmProContYield.getTenantId());
                pmProContYield.setPmPdSlab(pmPdSlab);
            }
            if (Objects.nonNull(pmPdSlab)) {
                Map<String, String> checkFlag = check(pmPdSlab.getSlabNo(), pmPdSlab.getPono(), orderNoList, organizationId , true);
                if(!checkFlag.containsKey(orderNo)) {
                    // 如果结果中不含
                    checkFlag = check(pmPdSlab.getSlabNo(), pmPdSlab.getPono(), orderNoList, organizationId, false);
                } 
                if (checkFlag.containsKey(orderNo) && "不合格".equals(checkFlag.get(orderNo))) {
                    throw new CommonException("材料【"+ pmPdSlab.getSlabNo() +"】与合同【"+orderNo+"】的低倍要求比对未通过");
                }
            }
        } else {
            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.LOW_POWER_REQUIREMENT.name() + "." + matNo;
        if (!queryCache) {
            if (orderNoList == null || orderNoList.isEmpty()) {
                return Maps.newHashMap();
            }
            List<QdSurplusLowMagnificationDTO> dtoList = new ArrayList<QdSurplusLowMagnificationDTO>(
                    orderNoList.size());
            for (String orderNo : orderNoList) {
                QdSurplusLowMagnificationDTO phyFurnaceChemicalMatchDTO = new QdSurplusLowMagnificationDTO();
                phyFurnaceChemicalMatchDTO.setOrderNo(orderNo);
                phyFurnaceChemicalMatchDTO.setPono(pono);
                dtoList.add(phyFurnaceChemicalMatchDTO);
            }
            List<QdSurplusLowMagnificationDTO> reslut = qdOrderClient.surplusLowMagnificationMatchApi(organizationId,
                    dtoList);
            if(reslut != null && !reslut.isEmpty()) {
                for (QdSurplusLowMagnificationDTO qdSurplusLowMagnificationDTO : reslut) {
                    checkFlag.put(qdSurplusLowMagnificationDTO.getOrderNo(), qdSurplusLowMagnificationDTO.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();
        }
    }

}
