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

import com.xisc.pm.api.dto.PmCompositeSlabCalcDTO;
import com.xisc.pm.api.dto.PmProContFilterRequestDTO;
import com.xisc.pm.api.dto.PmProContFilterResposeDTO;
import com.xisc.pm.api.dto.PmProContYieldRequestDTO;
import com.xisc.pm.api.dto.PmProContYieldResposeDTO;
import com.xisc.pm.api.dto.RuleParamDTO;
import com.xisc.pm.app.service.PmPdCcSlabService;
import com.xisc.pm.app.service.strategy.PdMatTypeStrategyFactory;
import com.xisc.pm.domain.entity.PmContMscTech;
import com.xisc.pm.domain.entity.PmPdCcSlab;
import com.xisc.pm.domain.entity.PmPdContSum;
import com.xisc.pm.domain.entity.PmProContProdTtr;
import com.xisc.pm.domain.entity.PmSlabSpecBt;
import com.xisc.pm.domain.entity.PmSmallPltPos;
import com.xisc.pm.domain.repository.PmPdCcSlabRepository;
import com.xisc.pm.domain.vo.CtMainVO;
import com.xisc.pm.infra.constant.Constants;
import com.xisc.pm.infra.enums.PdEventType;
import com.xisc.pm.infra.enums.PdMatType;
import com.xisc.pm.infra.enums.PdProdFlag;
import com.xisc.pm.infra.enums.PdRuleSetType;
import io.choerodon.core.exception.CommonException;
import org.apache.commons.lang3.StringUtils;
import org.hzero.core.message.Message;
import org.hzero.core.message.MessageAccessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

/**
 * 连铸出钢材组板
 * 
 * @author jun.zeng
 *
 */
@Component
public class CcSlabPdMatTypeStratrgy extends DefaultPdMatTypeStrategy<PmPdCcSlab> {

    @Autowired
    private PmPdCcSlabService pmPdCcSlabService;

    @Autowired
    private PmPdCcSlabRepository pmPdCcSlabRepository;

    @Override
    public void afterPropertiesSet() throws Exception {
        PdMatTypeStrategyFactory.register(PdMatType.C, this);
    }

    @Override
    public void contFilterInitParam(PmProContFilterRequestDTO pmProContFilterRequest) {
        pmProContFilterRequest.check();
    }

    @Override
    public boolean contFilterRuleSetCheck(PmProContFilterRequestDTO pmProContFilterRequest,
            PmProContFilterResposeDTO pmProContFilterResposeDTO, List<PmSlabSpecBt> pmSlabSpecBts,
            Map<String, CtMainVO> cmCtMainMap) {
        RuleParamDTO ruleParam = initContFilterRuleParam(PdRuleSetType.C01, pmProContFilterResposeDTO,
                pmProContFilterRequest, pmSlabSpecBts);
        ruleParam.buildExcludeRuleNo(pmProContFilterRequest);
        try {
            pmPdRuleSetService.runRuleSet(ruleParam);
            return true;
        } catch (CommonException e) {
            Message message = MessageAccessor.getMessage(e.getCode(), e.getParameters());
            pmProContFilterResposeDTO.setUnSelectedReason(message.getDesc());
            return false;
        }
    }

    @Override
    public RuleParamDTO contSelectionRuleSet() {
        return new RuleParamDTO(PdRuleSetType.C03);
    }

    @Override
    public RuleParamDTO contSelectionCheckRuleSet() {
        return new RuleParamDTO(PdRuleSetType.C04);
    }

    @Override
    public RuleParamDTO pdResultCheckRuleSet() {
        return new RuleParamDTO(PdRuleSetType.C05);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public PmPdCcSlab generateResult(PmProContYieldRequestDTO pmProContYield,
            Map<String, PmProContFilterResposeDTO> filterOrderMap, PmCompositeSlabCalcDTO pmCompositeSlabCalc,
            PmProContYieldResposeDTO pmProContYieldRespose, PmContMscTech axisPmContMscTech,
            PmProContProdTtr axisPmProContProdTtr) {
        return pmPdCcSlabService.createPmPdCcSlab(pmProContYield, filterOrderMap, pmCompositeSlabCalc,
                pmProContYieldRespose, axisPmContMscTech, axisPmProContProdTtr);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void generateCmd(PmPdCcSlab matParam, List<PmPdContSum> pmPdContSums, List<PmSmallPltPos> pmSmallPltPoss,
            String mscLineNo) {
        // 连铸出钢材组板，执行时不生成命令表数据
    }

    @Override
    public void yiledCalcBeforeCheck(PmProContYieldRequestDTO pmProContYield, boolean isExec) {
        pmProContYield.getPmContFilterRequest().check();
        if (isExec) {
            if (StringUtils.isBlank(pmProContYield.getVirtualSlabNo())) {
                throw new CommonException("pm.pm_pro_cont_039");
            }
            PmPdCcSlab record = new PmPdCcSlab();
            record.setTenantId(pmProContYield.getTenantId());
            record.setVirtualSlabNo(pmProContYield.getVirtualSlabNo());
            int count = this.pmPdCcSlabRepository.selectCount(record);
            if (count > 0) {
                throw new CommonException("pm.pm_pro_cont_042", pmProContYield.getVirtualSlabNo());
            }
            
        }
    }

    @Override
    public boolean needPlateCut() {
        return true;
    }
    
    @Override
    public String pdProgram() {
        return Constants.PdProgram.CC_SLAB_FINSHED_PD_PROGRAM;
    }
    
    @Override
    protected PdEventType pdDeleteEventType() {
        return PdEventType.HP17;
    }

    @Override
    protected PdEventType pdFinshedEventType() {
        return PdEventType.HP16;
    }
    
    @Override
    protected Long ctEventBoardPpFlag(PmPdCcSlab t, PmProContYieldRequestDTO pmProContYield) {
        return PdProdFlag.VIRTUAL_SLAB.getCode();
    }

    @Override
    protected String getWholeBacklogCode(PmProContFilterResposeDTO axisPmProCont, PmProContYieldRequestDTO pmProContYield) {
        return Constants.WholeBacklogCode.CODE_14;
    }

    @Override
    protected void checkCommandYield(PmProContYieldResposeDTO yieldRespose, PmProContYieldRequestDTO pmProContYield) {
        // 出钢材组板、余坯组板非指定长时，校验：若命令收得率小于限制收得率LIMIT_YIELD，返回消息：命令收得率【命令收得率】小于限制收得率【限制收得率】，不能组板！
        Long flag = 0L;
        if (flag.equals(pmProContYield.getPmContFilterRequest().getFixSlabLenFlag()) && pmProContYield.getPmContFilterRequest().getLimitYield() != null
        && pmProContYield.getPmContFilterRequest().getLimitYield().compareTo(yieldRespose.getCommandYield()) > 0) {
            throw new CommonException("pm.pm_pro_cont_066", yieldRespose.getCommandYield(), pmProContYield.getPmContFilterRequest().getLimitYield());
        }
    }
}
