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

import com.xisc.pm.app.service.PmCmdLargePltService;
import com.xisc.pm.domain.entity.PmCmdCont;
import com.xisc.pm.domain.entity.PmCmdLargePlt;
import com.xisc.pm.domain.entity.PmCmdSlab;
import com.xisc.pm.domain.entity.PmCmdSmallPlt;
import com.xisc.pm.domain.entity.PmCompositeSlabDiv;
import com.xisc.pm.domain.entity.PmPdPlateCut;
import com.xisc.pm.domain.repository.PmCmdContRepository;
import com.xisc.pm.domain.repository.PmCmdLargePltRepository;
import com.xisc.pm.domain.repository.PmCmdSlabRepository;
import com.xisc.pm.domain.repository.PmCmdSmallPltRepository;
import com.xisc.pm.domain.repository.PmCompositeSlabDivRepository;
import com.xisc.pm.domain.repository.PmPdPlateCutRepository;
import com.xisc.pm.domain.vo.PmCmdContVO;
import com.xisc.pm.domain.vo.PmCmdLargePltVO;
import com.xisc.pm.domain.vo.PmCmdSlabVO;
import com.xisc.pm.domain.vo.PmCmdSmallPltVO;
import com.xisc.pm.domain.vo.PmCmdVO;
import com.xisc.pm.domain.vo.PmCompositeSlabDivVO;
import com.xisc.pm.domain.vo.PmPdPlateCutVO;
import com.xisc.pm.infra.enums.CutPositionType;
import com.xisc.pm.infra.util.BeanUtils;
import io.choerodon.core.domain.Page;
import io.choerodon.core.domain.PageInfo;
import io.choerodon.mybatis.pagehelper.PageHelper;
import io.choerodon.mybatis.pagehelper.domain.PageRequest;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 命令大板表(PmCmdLargePlt)应用服务
 *
 * @author 纪文桃 wentao.ji01@hand-china.com
 * @since 2024-08-01 10:24:40
 */
@Service
public class PmCmdLargePltServiceImpl implements PmCmdLargePltService {

    private PmCmdLargePltRepository pmCmdLargePltRepository;

    private PmPdPlateCutRepository pmPdPlateCutRepository;
    
    @Autowired
    private PmCmdSlabRepository pmCmdSlabRepository;
    
    @Autowired
    private PmCmdSmallPltRepository pmCmdSmallPltRepository;
    
    @Autowired
    private PmCmdContRepository pmCmdContRepository;
    
    @Autowired
    private PmCompositeSlabDivRepository pmCompositeSlabDivRepository;
    
    public PmCmdLargePltServiceImpl(PmCmdLargePltRepository pmCmdLargePltRepository, PmPdPlateCutRepository pmPdPlateCutRepository) {
        this.pmCmdLargePltRepository = pmCmdLargePltRepository;
        this.pmPdPlateCutRepository = pmPdPlateCutRepository;
    }

    @Override
    public Page<PmCmdLargePlt> selectList(PageRequest pageRequest, PmCmdLargePlt pmCmdLargePlt) {
        Page<PmCmdLargePlt> page = PageHelper.doPage(pageRequest, () -> pmCmdLargePltRepository.selectList(pmCmdLargePlt));
        if (CollectionUtils.isEmpty(page.getContent())) {
            return page;
        }
        // 将合并板坯两块短坯排序到合并板坯后面
        List<String> ponoSlabNoList = new ArrayList<>();
        Map<String, List<PmCmdLargePlt>> cmdSlabMap = new HashMap<>(page.getContent().size());
        for (PmCmdLargePlt plt : page.getContent()) {
            if (StringUtils.isNotEmpty(plt.getPonoSlabNo())) {
                ponoSlabNoList.add(plt.getPonoSlabNo());
            }
        }
        List<String> mergePonoSlabNoList = new ArrayList<>();
        for (PmCmdLargePlt largePlt : page.getContent()) {
            if (StringUtils.isNotEmpty(largePlt.getSlabNo()) && ponoSlabNoList.contains(largePlt.getSlabNo())) {
                if (!cmdSlabMap.containsKey(largePlt.getSlabNo())) {
                    cmdSlabMap.put(largePlt.getSlabNo(), new ArrayList<>());
                }
                mergePonoSlabNoList.add(largePlt.getPonoSlabNo());
                cmdSlabMap.get(largePlt.getSlabNo()).add(largePlt);
            }
        }
        List<PmCmdLargePlt> resultList = new ArrayList<>();
        for (PmCmdLargePlt largePlt : page.getContent()) {
            if (CollectionUtils.isNotEmpty(mergePonoSlabNoList) && mergePonoSlabNoList.contains(largePlt.getPonoSlabNo())) {
                continue;
            }
            resultList.add(largePlt);
            if (cmdSlabMap.containsKey(largePlt.getPonoSlabNo())) {
                resultList.addAll(cmdSlabMap.get(largePlt.getPonoSlabNo()));
            }
        }
        return new Page<>(resultList, new PageInfo(pageRequest.getPage(), pageRequest.getSize()), page.getTotalElements());
    }

    @Override
    public void saveData(List<PmCmdLargePlt> pmCmdLargePlts) {
        List<PmCmdLargePlt> insertList = pmCmdLargePlts.stream().filter(line -> line.getPmCmdLargePltId() == null).collect(Collectors.toList());
        List<PmCmdLargePlt> updateList = pmCmdLargePlts.stream().filter(line -> line.getPmCmdLargePltId() != null).collect(Collectors.toList());
        pmCmdLargePltRepository.batchInsertSelective(insertList);
        pmCmdLargePltRepository.batchUpdateByPrimaryKeySelective(updateList);
    }

    @Override
    public Page<PmPdPlateCut> selectplatelist(PageRequest pageRequest, List<String> pdMatNoList, Long tenantId) {
        if (CollectionUtils.isEmpty(pdMatNoList)) {
            return new Page<>();
        }
        return PageHelper.doPageAndSort(pageRequest, () ->  pmPdPlateCutRepository.selectByPdMatNoList(pdMatNoList, tenantId));
    }
    
    @Override
    public Map<String, PmCmdVO> queryCmdVo(List<String> ponoSlabNoList , Long tenantId , boolean existsPmCmdSlab) {
        Map<String, PmCmdVO> cmdMap = new HashMap<String, PmCmdVO>();
        List<PmCmdLargePlt> pmCmdLargePlts = pmCmdLargePltRepository.selectByPonoSlabList(ponoSlabNoList, tenantId);
        Map<String , PmCmdSlab> pmCmdSlbMap = new HashMap<>();
        
        // 虚拟板坯号
        List<String> virtualSlabNo = new ArrayList<String>();
        Map<String,  String> ponoSlabNoToVirtualSlabNo = new HashMap<>();
        if(existsPmCmdSlab) {
            List<PmCmdSlab> pmCmdSlabs = pmCmdSlabRepository.selectByPonoSlabList(ponoSlabNoList, tenantId);
            if(pmCmdSlabs != null && !pmCmdSlabs.isEmpty()) {
                for (PmCmdSlab pmCmdSlab : pmCmdSlabs) {
                    pmCmdSlbMap.put(pmCmdSlab.getPonoSlabNo(), pmCmdSlab);
                    virtualSlabNo.add(pmCmdSlab.getVirtualSlabNo());
                    ponoSlabNoToVirtualSlabNo.put(pmCmdSlab.getPonoSlabNo(), pmCmdSlab.getVirtualSlabNo());
                }
            } else {
                // 如果命令表为空，可能是余材组板，虚拟板坯号=命令板坯号=临时板坯号
                virtualSlabNo.addAll(ponoSlabNoList);
            }
        } else {
            // 如果不存在命令板坯信息，是余材钢板，取钢板号做虚拟板坯号
            for (PmCmdLargePlt pmCmdLargePlt : pmCmdLargePlts) {
                virtualSlabNo.add(pmCmdLargePlt.getPlateNo());
                ponoSlabNoToVirtualSlabNo.put(pmCmdLargePlt.getPonoSlabNo(), pmCmdLargePlt.getPlateNo());
            }
        }
        
        Map<String , List<PmCmdSmallPlt>> pmCmdSmallPltMap = new HashMap<>();
        List<PmCmdSmallPlt> pmCmdSmallPlts = pmCmdSmallPltRepository.selectByPonoSlabList(ponoSlabNoList, tenantId);
        if(pmCmdSmallPlts != null && !pmCmdSmallPlts.isEmpty()) {
            pmCmdSmallPltMap = pmCmdSmallPlts.stream().collect(Collectors.groupingBy(PmCmdSmallPlt::getPonoSlabNo));
        }
        
        Map<String , List<PmCmdCont>> pmCmdContMap = new HashMap<>();
        List<PmCmdCont> pmCmdConts = pmCmdContRepository.selectByPonoSlabList(ponoSlabNoList, tenantId);
        if(pmCmdConts != null && !pmCmdConts.isEmpty()) {
            pmCmdContMap = pmCmdConts.stream().collect(Collectors.groupingBy(PmCmdCont::getPonoSlabNo));
        }
        
        Map<String , List<PmPdPlateCut>> pmPdPlateCutMap = new HashMap<>();
        List<PmPdPlateCut> pmPdPlateCuts = pmPdPlateCutRepository.selectByPdMatNoList(virtualSlabNo, tenantId);
        if(pmPdPlateCuts != null && !pmPdPlateCuts.isEmpty()) {
            pmPdPlateCutMap = pmPdPlateCuts.stream().collect(Collectors.groupingBy(PmPdPlateCut::getPdMatNo));
        }
        
        Map<String , List<PmCompositeSlabDiv>> pmCompositeSlabDivMap = new HashMap<>();
        List<PmCompositeSlabDiv> pmCompositeSlabDivs = pmCompositeSlabDivRepository.selectByPonoSlabList(ponoSlabNoList, tenantId);
        if(pmCompositeSlabDivs != null && !pmCompositeSlabDivs.isEmpty()) {
            pmCompositeSlabDivMap = pmCompositeSlabDivs.stream().collect(Collectors.groupingBy(PmCompositeSlabDiv::getPonoSlab));
        }
        
        for (PmCmdLargePlt pmCmdLargePlt : pmCmdLargePlts) {
            PmCmdVO pmCmdVO = new PmCmdVO();
            pmCmdVO.setPonoSlabNo(pmCmdLargePlt.getPonoSlabNo());
            pmCmdVO.setCmdLargePltVO(BeanUtils.copy(pmCmdLargePlt, PmCmdLargePltVO.class));
            if(pmCmdSlbMap != null && pmCmdSlbMap.containsKey(pmCmdLargePlt.getPonoSlabNo())) {
                pmCmdVO.setCmdSlabVO(BeanUtils.copy(pmCmdSlbMap.get(pmCmdLargePlt.getPonoSlabNo()), PmCmdSlabVO.class));
            }
            if(pmCmdSmallPltMap != null && !pmCmdSmallPltMap.isEmpty() && pmCmdSmallPltMap.containsKey(pmCmdLargePlt.getPonoSlabNo())) {
                List<PmCmdSmallPlt> pmCmdSmallPltList = pmCmdSmallPltMap.get(pmCmdLargePlt.getPonoSlabNo());
                pmCmdVO.setCmdSmallPltVOList(new ArrayList<>(pmCmdSmallPltList.size()));
                for (PmCmdSmallPlt pmCmdSmallPlt : pmCmdSmallPltList) {
                    pmCmdVO.getCmdSmallPltVOList().add(BeanUtils.copy(pmCmdSmallPlt, PmCmdSmallPltVO.class));
                }
            }
            if(pmCmdContMap != null && !pmCmdContMap.isEmpty() && pmCmdContMap.containsKey(pmCmdLargePlt.getPonoSlabNo())) {
                List<PmCmdCont> pmCmdContList = pmCmdContMap.get(pmCmdLargePlt.getPonoSlabNo());
                pmCmdVO.setCmdContVOList(new ArrayList<>(pmCmdContList.size()));
                for (PmCmdCont pmCmdCont : pmCmdContList) {
                    pmCmdVO.getCmdContVOList().add(BeanUtils.copy(pmCmdCont, PmCmdContVO.class));
                }
            }
            if(pmCompositeSlabDivMap != null && !pmCompositeSlabDivMap.isEmpty() && pmCompositeSlabDivMap.containsKey(pmCmdLargePlt.getPonoSlabNo())) {
                List<PmCompositeSlabDiv> pmCompositeSlabDivList = pmCompositeSlabDivMap.get(pmCmdLargePlt.getPonoSlabNo());
                pmCmdVO.setCompositeSlabDivVOList(new ArrayList<>(pmCompositeSlabDivList.size()));
                for (PmCompositeSlabDiv pmCompositeSlabDiv : pmCompositeSlabDivList) {
                    pmCmdVO.getCompositeSlabDivVOList().add(BeanUtils.copy(pmCompositeSlabDiv, PmCompositeSlabDivVO.class));
                }
            }
            String pdMatNo = ponoSlabNoToVirtualSlabNo.getOrDefault(pmCmdLargePlt.getPonoSlabNo(), pmCmdLargePlt.getPonoSlabNo());
            if(pmPdPlateCutMap != null && !pmPdPlateCutMap.isEmpty() && pmPdPlateCutMap.containsKey(pdMatNo)) {
                List<PmPdPlateCut> pmPdPlateCutList = pmPdPlateCutMap.get(pdMatNo);
                pmCmdVO.setPdPlateCutVOList(new ArrayList<>(pmPdPlateCutList.size()));
                for (PmPdPlateCut pmPdPlateCut : pmPdPlateCutList) {
                    if(CutPositionType.F.getCode().equals(pmPdPlateCut.getPositionType())) {
                        pmCmdVO.getPdPlateCutVOList().add(BeanUtils.copy(pmPdPlateCut, PmPdPlateCutVO.class));
                    }
                }
                if(pmCmdVO.getPdPlateCutVOList() != null && !pmCmdVO.getPdPlateCutVOList().isEmpty()) {
                    pmCmdVO.getPdPlateCutVOList().sort(new Comparator<PmPdPlateCutVO>() {
                        @Override
                        public int compare(PmPdPlateCutVO o1, PmPdPlateCutVO o2) {
                            if(o1.getPositionSeq() == null) {
                                return -1 ;
                            }
                            if(o2.getPositionSeq() == null) {
                                return 1 ;
                            }
                            return o1.getPositionSeq().compareTo(o2.getPositionSeq());
                        }
                    });
                }
            }
            cmdMap.put(pmCmdLargePlt.getPonoSlabNo(), pmCmdVO);
        }
        
        return cmdMap;
    }
}

