package com.xisc.pm.app.service.impl;

import com.xisc.boot.common.feign.pojo.MtUserInfo;
import com.xisc.boot.common.sys.UserClient;
import com.xisc.pm.api.dto.PmCmdRecordDTO;
import com.xisc.pm.api.dto.PmCmdRecordResDTO;
import com.xisc.pm.app.service.PmPdSlabInfoService;
import com.xisc.pm.app.service.strategy.SecondaryDesignStrategyFactory;
import com.xisc.pm.domain.entity.MmSlab;
import com.xisc.pm.domain.entity.PmCmdLargePlt;
import com.xisc.pm.domain.entity.PmCmdRecord;
import com.xisc.pm.domain.entity.PmCmdSlab;
import com.xisc.pm.domain.entity.PmCompositeSlab;
import com.xisc.pm.domain.entity.PmCompositeSlabList;
import com.xisc.pm.domain.entity.PmContMscTech;
import com.xisc.pm.domain.entity.PmPdCcSlab;
import com.xisc.pm.domain.entity.PmPdSlabInfo;
import com.xisc.pm.domain.entity.PmPlateThickAddvBt;
import com.xisc.pm.domain.entity.PmProContProdTtr;
import com.xisc.pm.domain.entity.PmRecordPonoProc;
import com.xisc.pm.domain.repository.PmCmdLargePltRepository;
import com.xisc.pm.domain.repository.PmCmdRecordRepository;
import com.xisc.pm.domain.repository.PmCmdSlabRepository;
import com.xisc.pm.domain.repository.PmPdSlabInfoRepository;
import com.xisc.pm.domain.repository.PmPlateThickAddvBtRepository;
import com.xisc.pm.domain.repository.PmRecordPonoProcRepository;
import com.xisc.pm.infra.constant.Constants.AutoManualFlag;
import com.xisc.pm.infra.constant.Constants.PdStatusHp;
import com.xisc.pm.infra.constant.Constants.WholeBacklogCode;
import com.xisc.pm.infra.constant.RuleSetConstants;
import com.xisc.pm.infra.enums.PdMatType;
import com.xisc.pm.infra.mapper.PmPdSlabInfoMapper;
import com.xisc.pm.infra.util.BeanUtils;
import io.choerodon.core.domain.Page;
import io.choerodon.core.domain.PageInfo;
import io.choerodon.core.oauth.CustomUserDetails;
import io.choerodon.core.oauth.DetailsHelper;
import io.choerodon.mybatis.pagehelper.PageHelper;
import io.choerodon.mybatis.pagehelper.domain.PageRequest;
import io.seata.spring.annotation.GlobalTransactional;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.hzero.core.base.BaseConstants;
import org.hzero.mybatis.domian.Condition;
import org.hzero.mybatis.util.Sqls;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 板坯信息表(PmPdSlabInfo)应用服务
 *
 * @author 纪文桃 wentao.ji01@hand-china.com
 * @since 2024-08-12 14:59:22
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class PmPdSlabInfoServiceImpl implements PmPdSlabInfoService {
    
    private static final Logger LOG = LoggerFactory.getLogger(PmPdSlabInfoServiceImpl.class);
    
    @Autowired
    private PmPdSlabInfoRepository pmPdSlabInfoRepository;

    @Autowired
    private PmPdSlabInfoMapper pmPdSlabInfoMapper;

    @Autowired
    private PmCmdSlabRepository pmcmdSlabRepository;

    @Autowired
    private PmCmdLargePltRepository pmCmdLargePltRepository;

    @Autowired
    private PmPlateThickAddvBtRepository pmPlateThickAddvBtRepository;

    @Autowired
    private PmRecordPonoProcRepository pmRecordPonoProcRepository;

    @Autowired
    private PmCmdRecordRepository pmCmdRecordRepository;

    @Autowired
    private UserClient userClient;


    @Override
    public Page<PmPdSlabInfo> selectList(PageRequest pageRequest, PmPdSlabInfo pmPdSlabInfo) {
        return PageHelper.doPageAndSort(pageRequest, () -> pmPdSlabInfoRepository.selectList(pmPdSlabInfo));
    }

    @Override
    public void saveData(List<PmPdSlabInfo> pmPdSlabInfos) {
        List<PmPdSlabInfo> insertList = pmPdSlabInfos.stream().filter(line -> line.getPmPdSlabInfoId() == null).collect(Collectors.toList());
        List<PmPdSlabInfo> updateList = pmPdSlabInfos.stream().filter(line -> line.getPmPdSlabInfoId() != null).collect(Collectors.toList());
        pmPdSlabInfoRepository.batchInsertSelective(insertList);
        pmPdSlabInfoRepository.batchUpdateByPrimaryKeySelective(updateList);
    }

    @Override
    public Map<String, Object> sampleAdditionQuery(PmCmdLargePlt dto, Long organizationId, int page, int size) {
        Map<String, Object> pageData = new HashMap<>();
        List<PmCmdLargePlt> largePltList = Collections.emptyList();
        if (RuleSetConstants.OUT_STEEL.equals(dto.getQueryType())) {
            // 查询命令板坯表（PM_CMD_SLAB）中所有组板状态为‘18’至‘24’（质量试样添加完成），材料设计种类为‘C’
            List<PmCmdSlab> pmCmdSlabList = pmcmdSlabRepository.selectByCondition(Condition.builder(PmCmdSlab.class)
                    .andWhere(Sqls.custom()
                    .andLessThanOrEqualTo(PmCmdSlab.FIELD_PONO, dto.getPonoUpperLimit(), true)
                    .andGreaterThanOrEqualTo(PmCmdSlab.FIELD_PD_STATUS_HP, "18")
                    .andLessThan(PmCmdSlab.FIELD_PD_STATUS_HP, "24")
                    .andEqualTo(PmCmdLargePlt.FIELD_MAT_DESIGN_KIND, "C")
                    .andEqualTo(PmCmdSlab.FIELD_TENANT_ID, organizationId))
                    .andWhere(Sqls.custom().andGreaterThanOrEqualTo(PmCmdSlab.FIELD_PONO, dto.getPonoLowerLimit(), true))
                    .build());

            if (CollectionUtils.isNotEmpty(pmCmdSlabList)) {
                Map<String, PmCmdSlab> map = pmCmdSlabList.stream().collect(Collectors.toMap(PmCmdSlab::getTmpSlabNo, Function.identity()));
                List<String> tmpSlabNoList = pmCmdSlabList.stream().map(PmCmdSlab::getTmpSlabNo).collect(Collectors.toList());

                //根据临时命令板坯号查询命令大板表
                largePltList = pmCmdLargePltRepository.selectByCondition(Condition.builder(PmCmdLargePlt.class)
                        .andWhere(Sqls.custom().andIn(PmCmdLargePlt.FIELD_TMP_SLAB_NO, tmpSlabNoList)
                                .andEqualTo(PmCmdLargePlt.FIELD_TENANT_ID, organizationId)).build());

                //封装数据
                for (PmCmdLargePlt largePlt : largePltList) {
                    PmCmdSlab pmCmdSlab = map.get(largePlt.getTmpSlabNo());
                    if (Objects.nonNull(pmCmdSlab)) {
                        encapsulateOutSteelData(largePlt, pmCmdSlab);
                    }
                }
            }
        } else if (RuleSetConstants.SURPLUS_SLAB.equals(dto.getQueryType())) {
            // 板坯号查询命令大板表（PM_CMD_LARGE_PLT），得到材料设计种类为“S”、组板状态＝‘18’至‘24’的
            List<PmCmdSlab> pmCmdSlabList = pmcmdSlabRepository.selectByCondition(Condition.builder(PmCmdSlab.class).andWhere(Sqls.custom()
                    .andGreaterThanOrEqualTo(PmCmdSlab.FIELD_PD_STATUS_HP, "18")
                    .andLessThan(PmCmdSlab.FIELD_PD_STATUS_HP, "24")
                    .andEqualTo(PmCmdLargePlt.FIELD_MAT_DESIGN_KIND, "S")
                    .andEqualTo(PmCmdSlab.FIELD_TENANT_ID, organizationId))
                    .andWhere(Sqls.custom().andLike(PmCmdSlab.FIELD_VIRTUAL_SLAB_NO, dto.getVirtualSlabNo(), true))
                    .build());
            if (CollectionUtils.isNotEmpty(pmCmdSlabList)) {
                Map<String, PmCmdSlab> map1 = pmCmdSlabList.stream().collect(Collectors.toMap(PmCmdSlab::getTmpSlabNo, Function.identity()));
                List<String> slabNoList = pmCmdSlabList.stream().map(PmCmdSlab::getSlabNo).collect(Collectors.toList());
                List<String> tmpSlabNoList = pmCmdSlabList.stream().map(PmCmdSlab::getTmpSlabNo).collect(Collectors.toList());
                //板坯信息表
                List<PmPdSlabInfo> slabInfoList = pmPdSlabInfoMapper.selectByCondition(Condition.builder(PmPdSlabInfo.class).andWhere(Sqls.custom()
                        .andIn(PmPdSlabInfo.FIELD_SLAB_NO, slabNoList)
                        .andEqualTo(PmPdSlabInfo.FIELD_TENANT_ID, organizationId)).build());
                Map<String, PmPdSlabInfo> map2 = new HashMap<>(slabInfoList.size());
                if (CollectionUtils.isNotEmpty(slabInfoList)) {
                    map2 = slabInfoList.stream().collect(Collectors.toMap(PmPdSlabInfo::getSlabNo, Function.identity()));
                }
                //命令大板表
                largePltList = pmCmdLargePltRepository.selectByCondition(Condition.builder(PmCmdLargePlt.class)
                        .andWhere(Sqls.custom().andIn(PmCmdLargePlt.FIELD_TMP_SLAB_NO, tmpSlabNoList)
                                .andEqualTo(PmCmdLargePlt.FIELD_TENANT_ID, organizationId)).build());
                //封装数据
                for (PmCmdLargePlt largePlt : largePltList) {
                    String tmpSlabNo = largePlt.getTmpSlabNo();
                    PmCmdSlab pmCmdSlab = map1.getOrDefault(tmpSlabNo, null);
                    if (Objects.nonNull(pmCmdSlab)) {
                        largePlt.setVirtualSlabNo(pmCmdSlab.getVirtualSlabNo());
                        PmPdSlabInfo pmPdSlabInfo = map2.getOrDefault(pmCmdSlab.getSlabNo(), null);
                        if (Objects.nonNull(pmPdSlabInfo)) {
                            encapsulateData(pmPdSlabInfo, largePlt, pmCmdSlab);
                        }
                    }
                }
            }
        } else if (RuleSetConstants.SURPLUS_STEEL_PLATE.equals(dto.getQueryType())) {
            // 钢板号PLATE_NO查询命令大板表（PM_CMD_LARGE_PLT），读取材料设计类型为P、组板状态为‘18’至‘24’的所有记录；
            largePltList = pmCmdLargePltRepository.selectByCondition(Condition.builder(PmCmdLargePlt.class)
                    .andWhere(Sqls.custom()
                            .andGreaterThanOrEqualTo(PmCmdLargePlt.FIELD_PD_STATUS_HP, "18")
                            .andLessThan(PmCmdLargePlt.FIELD_PD_STATUS_HP, "24")
                            .andEqualTo(PmCmdLargePlt.FIELD_MAT_DESIGN_KIND, "P"))
                    .andWhere(Sqls.custom().andEqualTo(PmCmdLargePlt.FIELD_PLATE_NO, dto.getPlateNo(), true))
                    .andWhere(Sqls.custom().andEqualTo(PmCmdLargePlt.FIELD_TENANT_ID, organizationId))
                    .build());
        }
        int totalPages = (int) Math.ceil((double) largePltList.size() / size);
        int startIndex = (page) * size;
        int endIndex = Math.min(startIndex + size, largePltList.size());
        List<PmCmdLargePlt> currentPageData = largePltList.subList(startIndex, endIndex);
        pageData.put("totalRecords", largePltList.size());
        pageData.put("totalPages", totalPages);
        pageData.put("pageSize", size);
        pageData.put("currentPage", page);
        pageData.put("data", currentPageData);
        return pageData;
    }

    public void encapsulateOutSteelData(PmCmdLargePlt largePlt, PmCmdSlab pmCmdSlab) {
        largePlt.setPono(pmCmdSlab.getPono());
        largePlt.setTmpSlabNo(pmCmdSlab.getTmpSlabNo());
        largePlt.setProdCodeHp(pmCmdSlab.getProdCodeHp());
        largePlt.setStNo(pmCmdSlab.getStNo());
        largePlt.setSgSign(pmCmdSlab.getSgSign());
        largePlt.setOrderNumInPlate(pmCmdSlab.getOrderNumInPlate());
        largePlt.setFormPlateTime(pmCmdSlab.getFormPlateTime());
        largePlt.setOrderRemainDiv(pmCmdSlab.getOrderRemainDiv());
        largePlt.setPdBacklogSeq(pmCmdSlab.getPdBacklogSeq());
        largePlt.setPdBacklogCode(pmCmdSlab.getPdBacklogCode());
        largePlt.setSlabNo(pmCmdSlab.getSlabNo());
        largePlt.setSlabDivNo(pmCmdSlab.getSlabDivNo());
        largePlt.setPdStatusHp(pmCmdSlab.getPdStatusHp());
        largePlt.setFurType(pmCmdSlab.getFurType());
        largePlt.setMatDesignKind(pmCmdSlab.getMatDesignKind());
        largePlt.setCoolCode(pmCmdSlab.getCoolCode());
        largePlt.setIngotType(pmCmdSlab.getIngotType());
    }

    public void encapsulateData(PmPdSlabInfo info, PmCmdLargePlt largePlt, PmCmdSlab pmCmdSlab) {
        largePlt.setPono(info.getPono());
        largePlt.setTmpSlabNo(pmCmdSlab.getTmpSlabNo());
        largePlt.setProdCodeHp(pmCmdSlab.getProdCodeHp());
        largePlt.setStNo(pmCmdSlab.getStNo());
        largePlt.setSgSign(pmCmdSlab.getSgSign());
        largePlt.setOrderNumInPlate(pmCmdSlab.getOrderNumInPlate());
        largePlt.setFormPlateTime(pmCmdSlab.getFormPlateTime());
        largePlt.setOrderRemainDiv(pmCmdSlab.getOrderRemainDiv());
        largePlt.setPdBacklogSeq(pmCmdSlab.getPdBacklogSeq());
        largePlt.setPdBacklogCode(pmCmdSlab.getPdBacklogCode());
        largePlt.setSlabNo(pmCmdSlab.getSlabNo());
        largePlt.setSlabDivNo(pmCmdSlab.getSlabDivNo());
        largePlt.setPdStatusHp(pmCmdSlab.getPdStatusHp());
        largePlt.setFurType(pmCmdSlab.getFurType());
        largePlt.setMatDesignKind(pmCmdSlab.getMatDesignKind());
        largePlt.setCoolCode(pmCmdSlab.getCoolCode());
        largePlt.setIngotType(pmCmdSlab.getIngotType());
    }

    @Override
    public void sampleAddition(List<PmCmdLargePlt> dtoList, Long organizationId) {
        
        //存在两种情况，1，勾选一组或多组数据，2，查询结果全部添加
        List<PmRecordPonoProc> pmRecordPonoProcList = new ArrayList<>();
        for (PmCmdLargePlt dto : dtoList) {
            //临时命令板坯号
            String tmpSlabNo = dto.getTmpSlabNo();
            //材料设计类型
            String matDesignKind = dto.getMatDesignKind();
            //命令板坯号
            String slabNo = dto.getPonoSlabNo();
            //制造命令号
            String pono = dto.getPono();
            //产线号
            String mscLineNo = dto.getMscLineNo();
            //母板宽度（组合板宽度）
            BigDecimal combinePlateWidth = dto.getCombinePlateWidth();
            //todo 调用质量接口
            //设置返回数据
            dto.setSampleLenHead(new BigDecimal("100"));
            dto.setSampleLenMid(new BigDecimal("100"));
            dto.setSampleLenTail(new BigDecimal("100"));
            dto.setSampleLenGive(new BigDecimal("100"));
            dto.setSampleLen(dto.getSampleLenHead().add(dto.getSampleLenMid()).add(dto.getSampleLenTail()).add(dto.getSampleLenGive()));
        }
        if (CollectionUtils.isNotEmpty(pmRecordPonoProcList)) {
            pmRecordPonoProcRepository.batchInsertSelective(pmRecordPonoProcList);
        }
    }
    
    @Override
    public void sampleAddition(String pdMatType, List<PmCmdLargePlt> dtoList, Long organizationId) {
        SecondaryDesignStrategyFactory.matchStrategy(pdMatType).sampleAddition(organizationId, dtoList);
    }

    public PmRecordPonoProc buildPmRecordPonoPrec(String precPono, String event, String reason, Long tenantId) {
        PmRecordPonoProc pmRecordPonoProc = new PmRecordPonoProc();
        pmRecordPonoProc.setPrecPono(precPono);
        pmRecordPonoProc.setEvent(event);
        pmRecordPonoProc.setReason(reason);
        pmRecordPonoProc.setTenantId(tenantId);
        return pmRecordPonoProc;
    }

    @Override
    public void sampleAdditionRollBack(List<String> tmpSlapNoList, Long organizationId , PdMatType pdMatType) {
        SecondaryDesignStrategyFactory.matchStrategy(pdMatType).sampleAdditionRollBack(organizationId, tmpSlapNoList);
    }

    @Override
    public void outSteelSecondaryDesign(List<PmCmdLargePlt> dtoList, Long organizationId) {
        SecondaryDesignStrategyFactory.matchStrategy(PdMatType.C).secondaryDesign(organizationId, dtoList);
    }

    @Override
    public void outSteelSecondaryDesignRollback(List<PmCmdLargePlt> dtoList, Long organizationId) {
        if(dtoList != null && !dtoList.isEmpty()) {
            SecondaryDesignStrategyFactory.matchStrategy(PdMatType.C).secondaryDesignRollback(organizationId, dtoList);
        }
    }

    @Override
    public void surplusSteelPlateSecondaryDesign(List<PmCmdLargePlt> dtoList, Long organizationId) {
        SecondaryDesignStrategyFactory.matchStrategy(PdMatType.P).secondaryDesign(organizationId, dtoList);
    }

    @Override
    public void surplusSteelPlateSecondaryDesignRollback(List<PmCmdLargePlt> dtoList, Long organizationId) {
        if(dtoList != null && !dtoList.isEmpty()) {
            SecondaryDesignStrategyFactory.matchStrategy(PdMatType.P).secondaryDesignRollback(organizationId, dtoList);
        }
    }

    @Override
    public void surplusSlabSecondaryDesign(List<PmCmdLargePlt> dtoList, Long organizationId) {
        SecondaryDesignStrategyFactory.matchStrategy(PdMatType.S).secondaryDesign(organizationId, dtoList);
    }

    @Override
    public void surplusSlabSecondaryDesignRollback(List<PmCmdLargePlt> dtoList, Long organizationId) {
        if(dtoList != null && !dtoList.isEmpty()) {
            SecondaryDesignStrategyFactory.matchStrategy(PdMatType.S).secondaryDesignRollback(organizationId, dtoList);
        }
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void outSteelCommandCreate(List<PmCmdLargePlt> dtoList, Long organizationId) {
        if(dtoList != null && !dtoList.isEmpty()) {
            SecondaryDesignStrategyFactory.matchStrategy(PdMatType.C).commandCreate(organizationId, dtoList);
            return ;
        }
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void surplusSteelCommandCreate(List<PmCmdLargePlt> dtoList, Long organizationId) {
        if(dtoList != null && !dtoList.isEmpty()) {
            SecondaryDesignStrategyFactory.matchStrategy(PdMatType.P).commandCreate(organizationId, dtoList);
            return ;
        }
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void surplusSlabCommandCreate(List<PmCmdLargePlt> dtoList, Long organizationId) {
        if(dtoList != null && !dtoList.isEmpty()) {
            SecondaryDesignStrategyFactory.matchStrategy(PdMatType.S).commandCreate(organizationId, dtoList);
            return ;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PmPdSlabInfo createFhbSlabInfo(MmSlab mmSlab, PmCompositeSlab pmCompositeSlab,
                                          PmCompositeSlabList pmCompositeSlabList, boolean isFhb) {
        CustomUserDetails userDetails = DetailsHelper.getUserDetails();
        PmPdSlabInfo pmPdSlabInfo = new PmPdSlabInfo();
        pmPdSlabInfo.setSlabNo(isFhb ? pmCompositeSlab.getSlabNo() : pmCompositeSlabList.getBaseMatNo());
        pmPdSlabInfo.setWholeBacklogSeq(mmSlab.getWholeBacklogSeq());
        pmPdSlabInfo.setWholeBacklogCode(mmSlab.getWholeBacklogCode());
        pmPdSlabInfo.setNextWholeBacklogSeq(mmSlab.getNextWholeBacklogSeq());
        pmPdSlabInfo.setNextWholeBacklogCode(mmSlab.getNextWholeBacklogCode());
        // 组批工序代码
        pmPdSlabInfo.setOuBacklogCode(WholeBacklogCode.CODE_13);
        // 组批工序顺序号
        pmPdSlabInfo.setOuBacklogSeq(3L);
        pmPdSlabInfo.setPono(mmSlab.getPono());
        pmPdSlabInfo.setMatStatus(mmSlab.getSlabStatus());
        // 长板坯标记
        pmPdSlabInfo.setSlabFlag("S");
        pmPdSlabInfo.setPdStatusHp(PdStatusHp.PD_STATUS_HP_18);
        pmPdSlabInfo.setAutoManualFlag(AutoManualFlag.AUTO_MANUA_FLAG_M);
        pmPdSlabInfo.setPdResp(userDetails == null ? "" : userDetails.getUserId().toString());
        pmPdSlabInfo.setStockCode(mmSlab.getStockCode());
        pmPdSlabInfo.setSgSign(mmSlab.getSgSign());
        pmPdSlabInfo.setStNo(mmSlab.getStNo());
        pmPdSlabInfo.setPrecStNo(mmSlab.getPreStNo());
//        pmPdSlabInfo.setDeciStNo(mmSlab.getdecis); TODO
//        pmPdSlabInfo.setFinStNo(mmSlab.GETFINS);
        pmPdSlabInfo.setMscLineNo(mmSlab.getMscLineNo());
        pmPdSlabInfo.setCanAssignFlag(BaseConstants.Flag.YES.toString());
        pmPdSlabInfo.setRemainCauseCode(mmSlab.getRemainCauseCode());
        pmPdSlabInfo.setComplexDecideCode(mmSlab.getComplexDecideCode());
        pmPdSlabInfo.setMatActThick(isFhb ? pmCompositeSlab.getActThick() : pmCompositeSlabList.getBaseMatThick());
        pmPdSlabInfo.setMatActLen(isFhb ? pmCompositeSlab.getActLength() : pmCompositeSlabList.getBaseMatLength());
        pmPdSlabInfo.setMatActWt(isFhb ? pmCompositeSlab.getActWt() : pmCompositeSlabList.getBaseMatWt());
        pmPdSlabInfo.setMatActWidth(isFhb ? pmCompositeSlab.getActWidth() : pmCompositeSlabList.getBaseMatWidth());
        pmPdSlabInfo.setMatTheoryWt(isFhb ? pmCompositeSlab.getActWt() : pmCompositeSlabList.getBaseMatWt());
//        pmPdSlabInfo.setSlabPlaceCode(mmSlab.getpl);
//        pmPdSlabInfo.setbd
        pmPdSlabInfo.setCcType(BaseConstants.Flag.YES.toString());
        pmPdSlabInfo.setCompositeSlabNo(isFhb ? "" : pmCompositeSlab.getSlabNo());
        pmPdSlabInfo.setSlabType(pmCompositeSlab.getSlabType());
        this.pmPdSlabInfoRepository.insertSelective(pmPdSlabInfo);
        return pmPdSlabInfo;
    }

    /**
     * 获取轧制产线号
     *
     * @param pmPdCcSlab
     * @return
     */
    protected String getRollLineNo(PmPdCcSlab pmPdCcSlab) {
        return pmPdCcSlab.getMscLineNo()
                .substring(pmPdCcSlab.getMscLineNo().length() - 2);
    }

    public PmPlateThickAddvBt selectTaimAddv(Long tenantId, PmProContProdTtr axisPmProContProdTtr,
                                             PmContMscTech axisPmContMscTech, String rollLineNo, PmPdCcSlab pmPdCcSlab) {
        String stCode = axisPmProContProdTtr.getProjectCode().substring(0, 2);
        List<PmPlateThickAddvBt> pmPlateThickAddvBts = pmPlateThickAddvBtRepository
                .selectByCondition(Condition.builder(PmPlateThickAddvBt.class)
                        .andWhere(Sqls.custom().andEqualTo(PmPlateThickAddvBt.FIELD_TENANT_ID, tenantId)
                                .andEqualTo(PmPlateThickAddvBt.FIELD_ST_CODE, stCode)
                                .andEqualTo(PmPlateThickAddvBt.FIELD_FORM_PLATE_MODE, pmPdCcSlab.getFormPlateMode())
                                .andEqualTo(PmPlateThickAddvBt.FIELD_AD_TYPE_MODE, axisPmContMscTech.getAdTypeCode())
                                .andEqualTo(PmPlateThickAddvBt.FIELD_ROLL_DIRECT_CODE, axisPmContMscTech.getRollDirectCode())
                                .andEqualTo(PmPlateThickAddvBt.FIELD_ROLL_MODE, axisPmContMscTech.getRollMode())
                                .andEqualTo(PmPlateThickAddvBt.FIELD_HEAT_TREAT_MODE, axisPmContMscTech.getWholeHeatTreatmentType())
                                .andEqualTo(PmPlateThickAddvBt.FIELD_ROLL_LINE_NO, rollLineNo)
                                .andGreaterThanOrEqualTo(PmPlateThickAddvBt.FIELD_PLATE_THICK_TO, axisPmProContProdTtr.getOrderThick())
                                .andLessThanOrEqualTo(PmPlateThickAddvBt.FIELD_PLATE_THICK_FROM, axisPmProContProdTtr.getOrderThick())
                                .andGreaterThanOrEqualTo(PmPlateThickAddvBt.FIELD_COMBINE_PLATE_WIDTH_TO, pmPdCcSlab.getCombinePlateWidth())
                                .andLessThanOrEqualTo(PmPlateThickAddvBt.FIELD_COMBINE_PLATE_WIDTH_FROM, pmPdCcSlab.getCombinePlateWidth())
                        )
                        .build());
        if (pmPlateThickAddvBts != null && !pmPlateThickAddvBts.isEmpty()) {
            return pmPlateThickAddvBts.get(0);
        }
        return null;
    }

    @Override
    public Page<PmCmdRecordResDTO> queryCmdRecord(PmCmdRecordDTO dto,PageRequest pageRequest, Long tenantId) {
        // 临时命令板坯号
        List<String> tmpSlabNoQueryList = new ArrayList<>();
        if (StringUtils.isNotEmpty(dto.getTmpSlabNo())) {
            tmpSlabNoQueryList.add(dto.getTmpSlabNo());
        }
        if (StringUtils.isNotEmpty(dto.getPonoLowerLimit()) || StringUtils.isNotEmpty(dto.getPonoUpperLimit()) ||
                StringUtils.isNotEmpty(dto.getVirtualSlabNo())) {
            // 查询命令参数表获取虚拟板坯号
            List<PmCmdSlab> pmCmdSlabList = pmcmdSlabRepository.selectByCondition(Condition.builder(PmCmdSlab.class)
                    .andWhere(Sqls.custom().andLessThanOrEqualTo(PmCmdSlab.FIELD_PONO, dto.getPonoUpperLimit(), true))
                    .andWhere(Sqls.custom().andGreaterThanOrEqualTo(PmCmdSlab.FIELD_PONO, dto.getPonoLowerLimit(), true))
                    .andWhere(Sqls.custom().andLike(PmCmdSlab.FIELD_VIRTUAL_SLAB_NO, dto.getVirtualSlabNo(), true))
                    .andWhere(Sqls.custom().andEqualTo(PmCmdSlab.FIELD_TENANT_ID, tenantId))
                    .build());
            tmpSlabNoQueryList.addAll(pmCmdSlabList.stream().map(PmCmdSlab::getTmpSlabNo).collect(Collectors.toList()));
        }
        // 查询履历表
        Page<PmCmdRecord> page = PageHelper.doPageAndSort(pageRequest, () -> pmCmdRecordRepository.selectByCondition(Condition.builder(PmCmdRecord.class)
                .andWhere(Sqls.custom().andEqualTo(PmCmdRecord.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andIn(PmCmdRecord.FIELD_TMP_SLAB_NO, tmpSlabNoQueryList, true))
                .andWhere(Sqls.custom().andLike(PmCmdRecord.FIELD_PLATE_NO, dto.getPlateNo(), true))
                .build()));
        if (CollectionUtils.isEmpty(page.getContent())) {
            return new Page<>();
        }

        // 关联查询命令大板表,命令板坯表
        List<String> tmpSlabNoList = page.getContent().stream().map(PmCmdRecord::getTmpSlabNo).distinct().collect(Collectors.toList());
        List<Long> operationIdList = page.getContent().stream().map(PmCmdRecord::getOperationId).distinct().map(Long::parseLong).collect(Collectors.toList());

        List<PmCmdLargePlt> pmCmdLargePltList = pmCmdLargePltRepository.selectByTmpSlabNoList(tmpSlabNoList, tenantId);
        Map<String, PmCmdLargePlt> pmCmdLargePltMap = pmCmdLargePltList.stream().collect(Collectors.toMap(PmCmdLargePlt::getTmpSlabNo, Function.identity()));
        List<PmCmdSlab> pmCmdSlabList = pmcmdSlabRepository.selectByTmpSlabNoList(tmpSlabNoList, tenantId);
        Map<String, PmCmdSlab> pmCmdSlabMap = pmCmdSlabList.stream().collect(Collectors.toMap(PmCmdSlab::getTmpSlabNo, Function.identity()));
        Map<Long, MtUserInfo> userInfoMap = userClient.userInfoBatchGet(tenantId, operationIdList);


        // 赋值
        List<PmCmdRecordResDTO> resList = new ArrayList<>();
        for (PmCmdRecord pmCmdRecord : page.getContent()) {
            PmCmdRecordResDTO res = buildPmCmdRecordDTO(pmCmdRecord, pmCmdLargePltMap, pmCmdSlabMap,  tenantId);
            //记录创建责任者
            MtUserInfo mtUserInfo = userInfoMap.get(Long.parseLong(res.getOperationId()));
            if (Objects.nonNull(mtUserInfo)) {
                res.setOperationId(mtUserInfo.getLoginName() + mtUserInfo.getRealName());
            }
            resList.add(res);
        }
        return new Page<>(resList, new PageInfo(pageRequest.getPage(), pageRequest.getSize()), page.getTotalElements());
    }

    private PmCmdRecordResDTO buildPmCmdRecordDTO(PmCmdRecord pmCmdRecord, Map<String, PmCmdLargePlt> pmCmdLargePltMap, Map<String, PmCmdSlab> pmCmdSlabMap, Long tenantId) {
        PmCmdRecordResDTO res = new PmCmdRecordResDTO();
        res.setPmCmdRecordId(pmCmdRecord.getPmCmdRecordId());
        res.setOperationName(pmCmdRecord.getOperationName());
        res.setOperationId(pmCmdRecord.getOperationId());
        res.setOperationTime(pmCmdRecord.getOperationTime());
        res.setPonoSlabNo(pmCmdRecord.getPonoSlabNo());
        res.setTmpSlabNo(pmCmdRecord.getTmpSlabNo());
        res.setMatDesignKind(pmCmdRecord.getMatDesignKind());
        res.setVirtualSlabNo(pmCmdRecord.getVirtualSlabNo());
        res.setSlabNo(pmCmdRecord.getSlabNo());
        res.setPlateNo(pmCmdRecord.getPlateNo());
        res.setTenantId(tenantId);
        if (pmCmdLargePltMap.containsKey(pmCmdRecord.getTmpSlabNo())) {
            PmCmdLargePlt pmCmdLargePlt = pmCmdLargePltMap.get(pmCmdRecord.getTmpSlabNo());
            BeanUtils.copy(pmCmdLargePlt, res);
        }
        if (pmCmdSlabMap.containsKey(pmCmdRecord.getTmpSlabNo())) {
            PmCmdSlab pmCmdSlab = pmCmdSlabMap.get(pmCmdRecord.getTmpSlabNo());
            BeanUtils.copy(pmCmdSlab, res);
        }
      return res;
    }
}
