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

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

import org.hzero.core.base.BaseConstants;
import org.hzero.mybatis.domian.Condition;
import org.hzero.mybatis.util.Sqls;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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.domain.repository.PmSlabSpecBtRepository;
import com.xisc.pm.infra.constant.RuleSetConstants;
import com.xisc.pm.infra.constant.Constants.RollDirectCode;
import com.xisc.pm.infra.enums.PdMatType;
import com.xisc.pm.infra.enums.PdRuleItemType;

import io.choerodon.core.exception.CommonException;

/**
 * 进加热炉长度基准限制检查（C05）
 * 
 * @author jun.zeng
 * 
 *
 * 
 */
@Component
public class InfurSlabLenRuleExecStrategy implements RuleExecStrategy {
    // 连铸板坯生产规格基准表PM_SLAB_SPEC_BT
    @Autowired
    protected PmSlabSpecBtRepository pmSlabSpecBtRepository;

    @Override
    public void afterPropertiesSet() throws Exception {
        RuleExecStrategyFactory.register(PdRuleItemType.INFUR_SLAB_LEN, 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);
        BigDecimal moldThick = (BigDecimal) bizData.get(RuleSetConstants.MOLD_THICK);
        BigDecimal moldWidth = (BigDecimal) bizData.get(RuleSetConstants.MOLD_WIDTH);
        BigDecimal infurSlabLen = (BigDecimal) bizData.get(RuleSetConstants.INFUR_SLAB_LEN);
        BigDecimal needSlabNo = (BigDecimal) bizData.get(RuleSetConstants.NEED_SLAB_LEN);
        Long tenantId = (Long) bizData.get(RuleSetConstants.TENANT_ID);
        String rollLineNo = (String) bizData.get(RuleSetConstants.ROLL_LINE_NO);
        String ccType = (String) bizData.get(RuleSetConstants.CC_TYPE);
        String matType = (String) bizData.get(RuleSetConstants.MAT_DESIGN_KIND);
        Integer rsCode = (Integer) bizData.get(RuleSetConstants.RS_CODE);
        String rollDirectCode = rsCode == 3 ? RollDirectCode.L : RollDirectCode.C;

        if (PdMatType.A.getCode().equals(matType) || PdMatType.B.getCode().equals(matType)
                || PdMatType.D.getCode().equals(matType)) {
            // 若组板材料设计种类mat_design_kind为A、B或者D，是钢锭组板，校验通过，继续下一规则校验。
            return true;
        }

        PmProContProdTtr axisPmProContProdTtr = (PmProContProdTtr) bizData
                .get(RuleSetConstants.AXIS_PM_PRO_CONT_PROD_ATTR);
        PmContMscTech axisPmContMscTech = (PmContMscTech) bizData.get(RuleSetConstants.AXIS_PM_CONT_MSC_TECH);

        if (axisPmContMscTech == null || axisPmProContProdTtr == null) {
            // 生产合同池没有找到记录，合同号【order_no】，产线号【msc_line_no】。
            throw new CommonException("pm.pm_pd_rule_set_001", orderNo, mscLineNo);
        }
        List<PmSlabSpecBt> specBts = pmSlabSpecBtRepository.selectByCondition(Condition.builder(PmSlabSpecBt.class)
                .andWhere(Sqls.custom().andEqualTo(PmSlabSpecBt.FIELD_TENANT_ID, tenantId)
                        .andEqualTo(PmSlabSpecBt.FIELD_ROLL_LINE_NO, rollLineNo)
                        .andEqualTo(PmSlabSpecBt.FIELD_ROLL_DIRECT_CODE, rollDirectCode)
                        .andGreaterThanOrEqualTo(PmSlabSpecBt.FIELD_SLAB_THICK_TO, moldThick)
                        .andLessThanOrEqualTo(PmSlabSpecBt.FIELD_SLAB_THICK_FROM, moldThick)
                        .andGreaterThanOrEqualTo(PmSlabSpecBt.FIELD_SLAB_WIDTH_TO, moldWidth)
                        .andLessThanOrEqualTo(PmSlabSpecBt.FIELD_SLAB_WIDTH_FROM, moldWidth)
                        .andGreaterThanOrEqualTo(PmSlabSpecBt.FIELD_SLAB_MAX_LEN, infurSlabLen)
                        .andLessThanOrEqualTo(PmSlabSpecBt.FIELD_SLAB_MIN_LEN, infurSlabLen)
                        .andEqualTo(PmSlabSpecBt.FIELD_CC_TYPE, ccType))
                .build());
        if (specBts == null || specBts.isEmpty()) {
            // 增加一次转置校验
            List<PmSlabSpecBt> specBts2 = pmSlabSpecBtRepository.selectByCondition(Condition.builder(PmSlabSpecBt.class)
                    .andWhere(Sqls.custom().andEqualTo(PmSlabSpecBt.FIELD_TENANT_ID, tenantId)
                            .andEqualTo(PmSlabSpecBt.FIELD_ROLL_LINE_NO, rollLineNo)
                            .andEqualTo(PmSlabSpecBt.FIELD_ROLL_DIRECT_CODE, rollDirectCode)
                            .andGreaterThanOrEqualTo(PmSlabSpecBt.FIELD_SLAB_THICK_TO, moldThick)
                            .andLessThanOrEqualTo(PmSlabSpecBt.FIELD_SLAB_THICK_FROM, moldThick)
                            .andGreaterThanOrEqualTo(PmSlabSpecBt.FIELD_SLAB_WIDTH_TO, infurSlabLen)
                            .andLessThanOrEqualTo(PmSlabSpecBt.FIELD_SLAB_WIDTH_FROM, infurSlabLen)
                            .andGreaterThanOrEqualTo(PmSlabSpecBt.FIELD_SLAB_MAX_LEN, moldWidth)
                            .andLessThanOrEqualTo(PmSlabSpecBt.FIELD_SLAB_MIN_LEN, moldWidth)
                            .andEqualTo(PmSlabSpecBt.FIELD_CC_TYPE, ccType))
                    .build());
            if (specBts2 == null || specBts2.isEmpty()) {
                String needSlabNoStr = needSlabNo == null ? "" : needSlabNo.toPlainString();
                // 获取连铸板坯生产规格基准表失败,轧制产线号【{0}】，轧制方向【{1}】，板坯厚度【{2}】，板坯宽度【{3}】，连铸机类型【{4}】，进加热炉板坯长【{5}】，必要板坯长度【{6}】
                throw new CommonException("pm.pm_pd_rule_set_019", rollLineNo, rollDirectCode, moldThick.toPlainString(),
                        moldWidth.toPlainString(), ccType, infurSlabLen.toPlainString() ,needSlabNoStr);
            }
        } 
        return true;
    }

}
