package com.xisc.pm.app.service.autoboard.dto;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;

import com.xisc.pm.domain.entity.PmAxisBrdTrimBt;
import com.xisc.pm.domain.entity.PmCutPlaceBt;
import com.xisc.pm.domain.entity.PmPdConstBt;
import com.xisc.pm.domain.entity.PmPlateCutLenBt;
import com.xisc.pm.domain.entity.PmPlateSpecBt;
import com.xisc.pm.domain.entity.PmPlateTrimBt;
import com.xisc.pm.domain.entity.PmProdLineSectionSpec;
import com.xisc.pm.domain.entity.PmSlabSpecBt;
import com.xisc.pm.domain.entity.PmSpeStAddvBt;
import com.xisc.pm.domain.entity.PmThickAddvBt;
import com.xisc.pm.infra.util.Utils;

import lombok.Data;

/**
 * 自动组板策略
 * 
 * @author jun.zeng
 *
 */
@Data
public class PmAutoBoardExecParam implements Serializable {

    private static final long serialVersionUID = 6281508617849119620L;
    
    private Long requestId ;

    // 设计产线号
    private String mscLineNo;
    // 断面厚
    private BigDecimal moldThick;
    // 断面宽
    private BigDecimal moldWidth;
    // 断面规格参数
    private List<PmProdLineSectionSpec> moldSpecs;
    
    // 钢种规格重量
    private BigDecimal steelSpecificationWeight ;
    
    // 断面ID 产线号_断面宽_断面厚
    private String moldId ;
    
    private PmAutoBoardPolicyDTO policy;
    
    // 组板常数
    private PmPdConstBt pmPdConstBt ;
    
    // 按断面 - 产线 - 连铸机类型 - 加热炉类型获取配置
    private List<PmSlabSpecBt> pmSlabSpecBts ;
    
    // 切边量
    private List<PmPlateTrimBt> pmPlateTrimBts;
    
    // 厚度余量
    private List<PmThickAddvBt> pmThickAddvBts ;
    
    // 钢板切缝宽度
    private List<PmPlateCutLenBt> pmPlateCutLenBts ;
    
    // 粗切位置
    private List<PmCutPlaceBt> pmCutPlaceBts ;
    
    // 获取板坯加料
    private List<PmSpeStAddvBt> pmSpeStAddvBts;
    
    // 特殊计算逻辑
    private List<PmAxisBrdTrimBt> pmAxisBrdTrimBts;
    
    // 钢板
    private List<PmPlateSpecBt> pmPlateSpecBts;

    // 下一个执行节点
    private PmAutoBoardExecParam nextNode;
    // 最后一个节点
    private PmAutoBoardExecParam lastNode;
    
    // 转置标记
    private boolean transflag = false;
    // 第二次计算标识
    private boolean secondTimeFlag ;
    // 产线变更标识-上一条产线最后一个断面会打上该标记，用来在产线计算完成之后，判断客户经济批量与钢种经济批量是否满足条件
    private boolean mscLineNoChangeFlag ;
    
    private boolean sPlusEnable = false;
    
    public PmAutoBoardExecParam() {
    }
    
    public PmAutoBoardExecParam(PmAutoBoardMoldDTO autoBoardMoldDTO) {
        this.mscLineNo = autoBoardMoldDTO.getMscLineNo();
        this.moldThick = autoBoardMoldDTO.getMoldThick();
        this.moldWidth = autoBoardMoldDTO.getMoldWidth();
        this.moldId = autoBoardMoldDTO.getMoldId();
        this.lastNode = this;
    }
    
    public void addNode(PmAutoBoardExecParam pmAutoBoardExecParam) {
        this.lastNode.setNextNode(pmAutoBoardExecParam);
        this.lastNode = pmAutoBoardExecParam.lastNode;
    }
    
    public void initSteelSpecificationWeight() {
        if(moldSpecs == null) {
            return ;
        }
        for (PmProdLineSectionSpec pmMoldSpec : this.moldSpecs) {
            if(pmMoldSpec.getSteelSpecificationWeight() != null) {
                steelSpecificationWeight = Utils.minValue(this.steelSpecificationWeight , pmMoldSpec.getSteelSpecificationWeight());
            }
        }
    }
    
    public boolean judgeOrderSpec(PmContBoardParam orderParam) {
        if(moldSpecs == null || moldSpecs.isEmpty()) {
            // 如果没限制规格，则不限制
            return true;
        }
        for (PmProdLineSectionSpec pmMoldSpec : this.moldSpecs) {
            if(judgeOrderSpec(orderParam, pmMoldSpec)) {
                return true ;
            };
        }
        return false ;
    }
    
    private boolean judgeOrderSpec(PmContBoardParam orderParam , PmProdLineSectionSpec spec) {
        if(orderParam.getOrderThick().compareTo(spec.getThickFrom()) < 0) {
            return false ;
        }
        if(orderParam.getOrderThick().compareTo(spec.getThickTo()) > 0) {
            return false ;
        }
        if(orderParam.getOrderWid().compareTo(spec.getWidFrom()) < 0) {
            return false ;
        }
        if(orderParam.getOrderWid().compareTo(spec.getWidTo()) > 0) {
            return false ;
        }
        if(orderParam.getSmallPlateLen().compareTo(spec.getLengthFrom()) < 0) {
            return false ;
        }
        if(orderParam.getSmallPlateLen().compareTo(spec.getLengthTo()) > 0) {
            return false ;
        }
        return true ;
    }

}
