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

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

import org.springframework.stereotype.Component;

import com.xisc.pm.api.dto.PmCompositeBlockDTO;
import com.xisc.pm.api.dto.PmCompositeBoardDTO;
import com.xisc.pm.api.dto.PmCompositeSlabCalcDTO;
import com.xisc.pm.api.dto.PmProContFilterResposeDTO;
import com.xisc.pm.api.dto.PmProContYieldDTO;
import com.xisc.pm.api.dto.PmProContYieldRequestDTO;
import com.xisc.pm.api.dto.PmSmallPlateDTO;
import com.xisc.pm.app.service.strategy.FormPlateModeStrategyFactory;
import com.xisc.pm.domain.entity.PmProContProdTtr;
import com.xisc.pm.domain.entity.PmSmallPltPos;
import com.xisc.pm.infra.enums.FormPlateMode;

import io.choerodon.core.exception.CommonException;

/**
 * 
 * 组板方式A处理策略
 * @author jun.zeng
 *
 */
@Component
public class FormPlateModeAStrategy extends DefaultFormPlateModeStrategy {
    
    @Override
    public List<BigDecimal> motherableEndPosList(FormPlateMode formPlateMode ,String matNo, Long tenantId, String rollLineNo , PmProContProdTtr axisPmProContProdTtr) {
        List<PmSmallPltPos> pmSmallPltPoss = pmSmallPltPosRepository.selectByPdMatNo(tenantId, matNo);
        pmSmallPltPoss.sort(new Comparator<PmSmallPltPos>() {
            @Override
            public int compare(PmSmallPltPos pos1, PmSmallPltPos pos2) {
                return pos1.getPickModeLenDir().compareTo(pos2.getPickModeLenDir());
            }
        });
        List<BigDecimal> motherableEndPosList = new ArrayList<BigDecimal>(pmSmallPltPoss.size());
        BigDecimal pos = BigDecimal.ZERO;
        for (PmSmallPltPos pmSmallPltPos : pmSmallPltPoss) {
            pos = pos.add(pmSmallPltPos.getSmallPlateLen());
            motherableEndPosList.add(pos);
        }

        return motherableEndPosList;
    }
    
    @Override
    public int maxBlockNum() {
        return 1;
    }
    
    @Override
    public void afterPropertiesSet() throws Exception {
        FormPlateModeStrategyFactory.register(FormPlateMode.A1, this);
        FormPlateModeStrategyFactory.register(FormPlateMode.A2, this);
    }
    
    @Override
    public PmCompositeSlabCalcDTO checkAndInitParams(Map<String, PmProContFilterResposeDTO> filterOrderMap, PmProContYieldRequestDTO pmProContYield, PmProContProdTtr axisPmProContProdTtr) {
        FormPlateMode mode = getFormPlateMode(pmProContYield);
        PmCompositeBoardDTO compositeBoard = pmProContYield.getCompositeBoard();
        
        PmCompositeSlabCalcDTO pmCompositeSlabCalcDTO = super.checkAndInitParams(filterOrderMap, pmProContYield , axisPmProContProdTtr);
        pmCompositeSlabCalcDTO.setPickModeWidDir(maxBlockNum());
        pmCompositeSlabCalcDTO.setPickModeLenDir(compositeBoard.getSpCount());
        pmCompositeSlabCalcDTO.setMotherableNum(compositeBoard.getSpCount());
        // A 型BLOCK一定是1,模板个数等于小板数
        
        
        Map<String, PmProContYieldDTO> pmProContYieldMap = getPmProContYieldDTOMap(filterOrderMap ,pmProContYield);
        
        PmCompositeBlockDTO block = compositeBoard.getPmCompositeBlockDTOs().get(0);
        
        for(int i = 0 ; i < block.getSmallPlateDTOList().size() ; i++) {
            PmSmallPlateDTO currnetSmallPlate = block.getSmallPlateDTOList().get(i);
            
            checkSmallPlateCount(currnetSmallPlate, filterOrderMap.get(currnetSmallPlate.getOrderNo()), pmProContYieldMap.get(currnetSmallPlate.getOrderNo()));
            
            pmCompositeSlabCalcDTO.getMLen().add(currnetSmallPlate.getSmallPlateLen());
            if(i > 0) {
                // 处理异宽
                PmSmallPlateDTO lastSmallPlate = block.getSmallPlateDTOList().get(i-1);
                if(!lastSmallPlate.getOrderWidth().equals(currnetSmallPlate.getOrderWidth())) {
                    if(FormPlateMode.A1.equals(mode)) {
                        throw new CommonException("pm.pm_pro_cont_016" , FormPlateMode.A1.getCode());
                    }
                    // 统计异宽
                    pmCompositeSlabCalcDTO.setDiffNum(pmCompositeSlabCalcDTO.getDiffNum() + 1);
                    pmCompositeSlabCalcDTO.getDiffLoc().add(i);
                }
            }
            
        }
        return pmCompositeSlabCalcDTO;
    }

    @Override
    public BigDecimal getSumPlateWt(Map<String, PmProContProdTtr> pmProContProdTtrs,
            PmProContYieldRequestDTO pmProContYield) {
        BigDecimal total = BigDecimal.ZERO;
        PmCompositeBlockDTO blockDTO = pmProContYield.getCompositeBoard().getPmCompositeBlockDTOs().get(0);
        for (PmSmallPlateDTO pmSmallPlateDTO : blockDTO.getSmallPlateDTOList()) {
            PmProContProdTtr pmProContProdTtr = pmProContProdTtrs.get(pmSmallPlateDTO.getOrderNo());
            total = total.add(pmProContProdTtr.getOrderUnitAimWt());
        }
        return total;
    }

    @Override
    public PmCompositeBoardDTO buildPmCompositeBoard(FormPlateMode formPlateMode,List<PmSmallPltPos> pmSmallPltPoss,
            PmProContProdTtr axisPmProContProdTtr, String mscLineNo, Long tenantId) {
        PmCompositeBoardDTO pmCompositeBoardDTO = new PmCompositeBoardDTO();
        List<PmCompositeBlockDTO> pmCompositeBlockDTOs = new ArrayList<>();
        pmCompositeBoardDTO.setPmCompositeBlockDTOs(pmCompositeBlockDTOs);
        PmCompositeBlockDTO pmCompositeBloc = getPmCompositeBlock(pmSmallPltPoss, 1L);
        pmCompositeBlockDTOs.add(pmCompositeBloc);
        
        pmCompositeBoardDTO.setOrderCount(pmCompositeBloc.getBlkOrderNum());
        pmCompositeBoardDTO.setBlkCount(1);
        pmCompositeBoardDTO.setPickModeWidDir(1);
        pmCompositeBoardDTO.setSpCount(pmSmallPltPoss.size());
        pmCompositeBoardDTO.setPickModeLenDir(pmSmallPltPoss.size());
        pmCompositeBoardDTO.setSzLength(pmCompositeBloc.getBlockLength());
        pmCompositeBoardDTO.setSzWidth(pmCompositeBloc.getBlockWidth());
        return pmCompositeBoardDTO;
    }

}
