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

import com.xisc.pm.api.dto.RuleParamDTO;
import com.xisc.pm.app.service.strategy.RuleExecStrategyFactory;
import com.xisc.pm.domain.entity.PmContMscTech;
import com.xisc.pm.domain.entity.PmProContProdTtr;
import com.xisc.pm.domain.entity.PmSlabSpecBt;
import com.xisc.pm.infra.constant.RuleSetConstants;
import com.xisc.pm.infra.enums.PdRuleItemType;
import io.choerodon.core.exception.CommonException;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Map;

/**
 * 板坯压下比检查 (C01)
 * 
 * 
 * 获取传入合同号order_no、板坯厚度mold_thick、产线号msc_line_no.根据合同号从生产合同产品属性表PM_PRO_CONT_PROD_ATTR获取合同厚度ORDER_THICK。
 * 根据合同号和去向产线号msc_line_no，从合同产线工艺参数表PM_CONT_MSC_TECH获取压缩比下限COMPRESS_MIN，则合同的最小允许板坯厚度
 * = COMPRESS_MIN * ORDER_THICK. 从连铸板坯生产规格基准表PM_SLAB_SPEC_BT，根据连铸机类型CC_TYPE,
 * 钢板厚度起止PLATE_THICK_FROM/TO包含ORDER_THICK，轧制产线号等于去向产线号后两位，获取板坯厚度止SLAB_THICK_TO的最大值，
 * 作为该合同最大允许板坯厚度。若没有找到记录，提示消息：读连铸板坯生产规格基准表没有找到记录，连铸机类型【CC_TYPE】，
 * 钢板厚度【ORDER_THICK】，轧制产线号【msc_line_no后两位】。
 * 如果板坯厚度mold_thick小于最小允许板坯厚度或大于最大允许板坯厚度，则提示消息报错：
 * 合同【ORDER_THICK】的允许板坯厚度范围【最小允许板坯厚度】（合同要求）-
 * 【最大允许板坯厚度】（连铸板坯生产规格基准表）与指定板坯厚度【mold_thick】不匹配。
 * 
 * @author jun.zeng
 *
 */
@Component
public class CompressMinRuleExecStrategy implements RuleExecStrategy {

    @Override
    public void afterPropertiesSet() throws Exception {
        RuleExecStrategyFactory.register(PdRuleItemType.SALB_COMPRESSION_RATIO, 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);
        String ccType = (String) bizData.get(RuleSetConstants.CC_TYPE);
        // 结晶器厚度
        BigDecimal moldThick = (BigDecimal) bizData.get(RuleSetConstants.MOLD_THICK);
        // 生产合同属性
        PmProContProdTtr pmProContProdTtr = (PmProContProdTtr) bizData.get(RuleSetConstants.PM_PRO_CONT_PROD_ATTR);
        if (null == pmProContProdTtr) {
            // 生产合同池没有找到记录，合同号【order_no】，产线号【msc_line_no】。
            throw new CommonException("pm.pm_pd_rule_set_001", orderNo, mscLineNo);
        }
        // 产线工艺参数
        PmContMscTech pmContMscTech = (PmContMscTech) bizData.get(RuleSetConstants.PM_CONT_MSC_TECH);
        if (null == pmContMscTech) {
            // 生产合同池没有找到记录，合同号【order_no】，产线号【msc_line_no】。
            throw new CommonException("pm.pm_pd_rule_set_001", orderNo, mscLineNo);
        }
        // 连铸板坯生产规格基准表
        PmSlabSpecBt pmSlabSpecBt = (PmSlabSpecBt) bizData.get(RuleSetConstants.PM_SLAB_SPEC_BT);
        BigDecimal compressMin = pmContMscTech.getCompressMin() == null ? BigDecimal.ZERO
                : pmContMscTech.getCompressMin();
        BigDecimal orderThick = pmProContProdTtr.getOrderThick() == null ? BigDecimal.ZERO
                : pmProContProdTtr.getOrderThick();
        if (null == pmSlabSpecBt) {
            // 读连铸板坯生产规格基准表没有找到记录，连铸机类型【CC_TYPE】，钢板厚度【ORDER_THICK】，轧制产线号【msc_line_no后两位】
            throw new CommonException("pm.pm_pd_rule_set_056" ,ccType , orderThick.toPlainString(), mscLineNo);
        }

//        BigDecimal minThick = compressMin.multiply(orderThick);
        BigDecimal minThick = pmContMscTech.getSlabThkMin() == null ? BigDecimal.ZERO : pmContMscTech.getSlabThkMin();
        BigDecimal maxThick = pmContMscTech.getSlabThkMax() == null ? null : pmContMscTech.getSlabThkMax();
        if (null == moldThick || moldThick.compareTo(minThick) < 0 || (maxThick != null && moldThick.compareTo(maxThick) > 0)) {
            // 合同【ORDER_THICK】的允许板坯厚度范围【最小允许板坯厚度:】（合同要求）-【最大允许板坯厚度:】（连铸板坯生产规格基准表）与指定板坯厚度【mold_thick】不匹配。
            throw new CommonException("pm.pm_pd_rule_set_005", orderThick.toPlainString(), minThick.toPlainString(),
                    maxThick == null ? "" : maxThick.toPlainString(), moldThick == null ? "" : moldThick.toPlainString());
        }

        return true;
    }

}
