package com.sw.mes.itemclean.clean.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.sw.mes.core.api.system.YbFeignClients;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.dto.CarrierConfigDto;
import com.sw.mes.core.dto.DictionaryItemDto;
import com.sw.mes.core.dto.materialCleanDto.MaterialCleanModelDto;
import com.sw.mes.core.enums.EnumValuesFactory;
import com.sw.mes.core.enums.ItemCleanEnums;
import com.sw.mes.core.exception.BusinessException;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultCode;
import com.sw.mes.core.utils.StringUtils;
import com.sw.mes.itemclean.clean.domain.*;
import com.sw.mes.itemclean.clean.dto.*;
import com.sw.mes.itemclean.clean.dto.boxNoOperate.BoxNoOperate;
import com.sw.mes.itemclean.clean.dto.boxNoOperate.MaterialNo;
import com.sw.mes.itemclean.clean.mapper.MaterialCleaningMapper;
import com.sw.mes.itemclean.clean.mapping.ScanBoxNoMapping;
import com.sw.mes.itemclean.clean.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 清洗 服务实现类
 * </p>
 *
 * @author liuzemin
 * @since 2022-11-10
 */
@Service
public class MaterialCleaningServiceImpl extends ServiceImpl<MaterialCleaningMapper, MaterialCleaning> implements MaterialCleaningService, ScanBoxNoService {

    @Autowired
    private MaterialStoreSignBoxService materialStoreSignBoxService;

    @Autowired
    private MaterialCleaningDetailService materialCleaningDetailService;

    @Autowired
    private MaterialCleaningBasketService materialCleaningBasketService;

    @Autowired
    private GenerateBusinessNoService generateBusinessNoService;

    @Autowired
    private MaterialCleaningDownService materialCleaningDownService;

    @Autowired
    YbFeignClients ybFeignClients;

    @Autowired
    MaterialApplyOrderService materialApplyOrderService;

    @Autowired
    MaterialUnpackingService materialUnpackingService;

    @Autowired
    private CleaningProcessFlowService cleaningProcessFlowService;

    private final static String BASKET_MARK = "AQ";

    @Override
    public BoxPropertyDto scanBoxNo(GeneralScanBoxNoParam param) {
        if (StringUtils.isBlank(param.getBoxNo()) || StringUtils.isBlank(param.getDeviceNo())) {
            throw new RuntimeException("设备号与箱号不能为空");
        }

        LambdaQueryWrapper<MaterialStoreSignBox> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialStoreSignBox::getMaterialBoxNo, param.getBoxNo());
        queryWrapper.eq(MaterialStoreSignBox::getPickingStatus, 1);
//        queryWrapper.in(MaterialStoreSignBox::getMaterialType, Arrays.asList(ItemCleanEnums.MaterialType.原生多晶.getKey()
//                                                                            ,ItemCleanEnums.MaterialType.回收料.getKey()
//                                                                            ,ItemCleanEnums.MaterialType.落地料.getKey()
//                                                                            ,ItemCleanEnums.MaterialType.返工料.getKey()));
        queryWrapper.last("limit 1");
        MaterialStoreSignBox box = materialStoreSignBoxService.getOne(queryWrapper);
        if (box == null) {
            throw new RuntimeException(param.getBoxNo() + "该箱号不存在！");
        }
        if (box.getIsEmptyBox() == 1) {
            throw new RuntimeException(param.getBoxNo() + "该箱号为空箱！");
        }
        if (box.getMaterialType() == ItemCleanEnums.MaterialType.原生多晶.getKey()
                || box.getMaterialType() == ItemCleanEnums.MaterialType.回收料.getKey()
                || box.getMaterialType() == ItemCleanEnums.MaterialType.落地料.getKey()
                || box.getMaterialType() == ItemCleanEnums.MaterialType.返工料.getKey()
        ) {
            BoxPropertyDto boxPropertyDto = ScanBoxNoMapping.toDto(box);
            CleanBoxPropertyDto cleanBoxPropertyDto = new CleanBoxPropertyDto(); //新的清洗扫箱子返回对象
            BeanUtils.copyProperties(boxPropertyDto, cleanBoxPropertyDto);

            checkIsNewBatcch(box.getProductBatchNo(), param.getDeviceNo(), cleanBoxPropertyDto); //检验新批次

            return cleanBoxPropertyDto;
        } else {
            throw new RuntimeException(param.getScanName() + ":当前箱号" + param.getBoxNo() + "属于" + ItemCleanEnums.MaterialType.getText(box.getMaterialType()));
        }
    }

    //判断扫的批次号,在当前设备未完结批次中是否是新的
    private void checkIsNewBatcch(String productBatchNo, String deviceNo, CleanBoxPropertyDto cleanBoxPropertyDto) {
        MaterialCleaning materialCleaning = getByBatchNoAndDevice(productBatchNo, deviceNo);
        if (materialCleaning != null) {
            checkExistBasketLastBatch(materialCleaning); //判断上一批次上料是否添加了花篮
            cleanBoxPropertyDto.setIsNewBatch(0);
        } else {
            List<MaterialCleaning> materialCleaningsByDevice = getByDevice(deviceNo);
            if (materialCleaningsByDevice.size() == 0) {
                cleanBoxPropertyDto.setIsNewBatch(2);
            } else {
                cleanBoxPropertyDto.setIsNewBatch(1);
            }
        }
    }

    //判断上一批次上料是否添加了花篮
    private void checkExistBasketLastBatch(MaterialCleaning materialCleaning) {
        List<MaterialCleaningBasket> baskets = materialCleaningBasketService.findByCleanId(materialCleaning.getId());
        if (baskets.size() == 0) {
            throw new RuntimeException("初始上料批次号" + materialCleaning.getProductBatchNo() + "未添加花篮号,无法继续上料");
        }
    }

    /**
     * 获取当前设备正在上下料信息
     *
     * @param deviceNo
     * @return
     */
    @Override
    public MaterialCleaning getCurrentCleanUpInfo(String deviceNo) {
        LambdaQueryWrapper<MaterialCleaning> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialCleaning::getDeviceNo, deviceNo);
        queryWrapper.eq(MaterialCleaning::getBatchEnd, 0);
        queryWrapper.orderByAsc(MaterialCleaning::getId);
        queryWrapper.last("limit 1");
        return getOne(queryWrapper);
    }

    /**
     * 清洗上料
     * @param dto
     */
  /*  @Override
    @Transactional(rollbackFor = Throwable.class)
    public void materialCleaningUp(MaterialCleaningUpDto dto) {
        //获取清洗任务MaterialCleaning
        MaterialCleaning materialCleaning = getMaterialCleaning(dto);
        saveOrUpdate(materialCleaning);

        //保存扫描的箱子至MaterialCleaningDetail
        MaterialCleaningDetail materialCleaningDetail = buildMaterialCleaningDetail(dto);
        materialCleaningDetail.setCleanId(materialCleaning.getId());
        materialCleaningDetailService.saveOrUpdate(materialCleaningDetail);

        //从MaterialStoreSign逻辑删除扫描的箱子
        materialStoreSignBoxService.discountBox(Arrays.asList(dto.getBoxInfo().getMaterialBoxNo()));

        //提交花篮信息
        if (dto.getBasketInfo() != null) {
            materialCleaningBasketChoose(new MaterialCleaningBasketChooseDto(materialCleaning.getId(), dto.getBasketInfo()));
        }
    }
*/

    /**
     * 新版清洗上料
     *
     * @param dto
     */
    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void materialCleaningUp(MaterialCleaningUpDto dto) {
        // 1 新增上料信息 2 过站; 3 更新物料重量信息,可能是领料表,或者是分选表
        BoxInfoDto boxInfo = dto.getBoxInfo();
        List<BasketInfoDto> basketInfo = dto.getBasketInfo();
        BasketInfoDto basketInfoDto = basketInfo.get(0);

        //调用详细入参上料
        materialDetailCleaningUp(dto.getDeviceNo(), boxInfo.getBoxNo(), boxInfo.getMaterialCode(), boxInfo.getMaterialName(), boxInfo.getMaterialLevel(), boxInfo.getMaterialModel(),
                boxInfo.getMaterialGear(), boxInfo.getCurrentProductBatchNo(), basketInfoDto.getBasketNo(), basketInfoDto.getWeight(), basketInfoDto.getBoxWeight(), basketInfoDto.getTypeName(),dto.getRemark());

    }

    /**
     * 详细入参-清洗上料
     *
     * @param deviceNo              设备号
     * @param preBoxNo              分选上料箱
     * @param materialCode          物料编码
     * @param materialName          物料名称
     * @param materialLevel         物料等级
     * @param materialModel         物料型号
     * @param materialGear          物料档位
     * @param currentProductBatchNo pp分选批次
     * @param basketNo              花篮号
     * @param weight                物料重量
     * @param boxWeight             花篮载具重量
     * @param boxTypeName           载具类型
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void materialDetailCleaningUp(String deviceNo, String preBoxNo, String materialCode, String materialName,
                                         String materialLevel, String materialModel, String materialGear,
                                         String currentProductBatchNo, String basketNo, BigDecimal weight,
                                         String boxWeight, String boxTypeName, String remark) {
        // 1 新增上料信息 2 过站; 3 更新物料重量信息,可能是领料表,或者是分选表
        if (StringUtils.isBlank(materialCode)) {
            throw new BusinessException("物料编码为空:" + materialCode);
        }
        MaterialCleaning materialCleaning = new MaterialCleaning();
        materialCleaning.setStatus(ItemCleanEnums.MaterialCleanStatus.清洗上料.getKey());
        materialCleaning.setBoxNo(basketNo);
        materialCleaning.setBoxWeight(boxWeight);
        materialCleaning.setTypeName(boxTypeName);
        materialCleaning.setPreBoxNo(preBoxNo);
        materialCleaning.setWeight(weight);
        materialCleaning.setMaterialCode(materialCode);
        materialCleaning.setMaterialName(materialName);
        materialCleaning.setMaterialLevel(materialLevel);
        materialCleaning.setMaterialModel(materialModel);
        materialCleaning.setMaterialGear(materialGear);
        materialCleaning.setProductBatchNo(currentProductBatchNo);
        materialCleaning.setCleanProductBatchNo(currentProductBatchNo);
        materialCleaning.setBatchEnd(0);
        materialCleaning.setDeviceNo(deviceNo);
        materialCleaning.setCreateUser(BaseContextHandler.getUsername());
        materialCleaning.setCreateTime(LocalDateTime.now());
        materialCleaning.setRemark(remark);
        saveOrUpdate(materialCleaning);

        //2 查询相关信息是分选表
        BigDecimal unusedWeightTotal = BigDecimal.ZERO;

        MaterialUnpacking materialUnpacking = materialUnpackingService.getUseInfoByPpProductBatchNo(currentProductBatchNo);
        if (null == materialUnpacking) {
            throw new BusinessException("批次" + currentProductBatchNo + "物料已经被合批或清空");
        }
        BigDecimal usedWeightTotal = materialUnpacking.getUsedWeight().add(weight);
        unusedWeightTotal = materialUnpacking.getWeight().subtract(usedWeightTotal);
        if (unusedWeightTotal.compareTo(BigDecimal.ZERO) < 0) {
            throw new BusinessException("该箱:" + preBoxNo + "分选表中物料重量不足!");
        } else if (unusedWeightTotal.compareTo(BigDecimal.ZERO) == 0) {
            materialUnpacking.setUseStatus(ItemCleanEnums.MaterialFxUseStatus.已清空.getKey());
        } else {
            materialUnpacking.setUseStatus(ItemCleanEnums.MaterialFxUseStatus.已使用.getKey());
        }
        materialUnpacking.setUpdateUser(BaseContextHandler.getUsername());
        materialUnpacking.setUpdateTime(LocalDateTime.now());
        materialUnpacking.setUsedWeight(usedWeightTotal);
        materialUnpacking.setUnusedWeight(unusedWeightTotal);
        materialUnpackingService.updateById(materialUnpacking);

        //2.3 过站(老批次,箱号出站;新批次,箱号进入下一站点)
        cleaningProcessFlowService.outStation(materialUnpacking.getFxProductBatchNo(), materialUnpacking.getFxProductBatchNo(), materialUnpacking.getWeight(), materialUnpacking.getUnusedWeight(), materialUnpacking.getUsedWeight(), "", EnumValuesFactory.CleaningWipStorageCode.分选.getValue(), "", materialUnpacking.getBoxNo(), EnumValuesFactory.CleaningWipStorageCode.分选.getValue(), EnumValuesFactory.CleaningWipStorageStatus.工序出站.getKey());
        cleaningProcessFlowService.inStation(materialUnpacking.getFxProductBatchNo(), materialUnpacking.getFxProductBatchNo(), materialCleaning.getWeight(), materialCleaning.getWeight(), BigDecimal.ZERO, materialCleaning.getDeviceNo(), EnumValuesFactory.CleaningWipStorageCode.清洗.getValue(), "", materialCleaning.getBoxNo(), EnumValuesFactory.CleaningWipStorageCode.清洗.getValue(), EnumValuesFactory.CleaningWipStorageStatus.工序进站.getKey());

    }

    /**
     * 原料清洗批次完结
     *
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void materialCleaningEnd(Integer id) {
        materialCleaningPackaging(id); //批次完结也打个箱

        MaterialCleaning materialCleaning = getById(id);
//        if (materialCleaning.getBatchEnd() == 0){
        materialCleaning.setBatchEnd(1);
//        }else {
//            materialCleaning.setBatchEnd(0);
//        }
        materialCleaning.setUpdateUser(BaseContextHandler.getUsername());
        materialCleaning.setUpdateTime(LocalDateTime.now());
        saveOrUpdate(materialCleaning);
    }

    /**
     * 原料清洗下料，打签成箱
     * @param id
     */
  /*  @Override
    @Transactional(rollbackFor = Throwable.class)
    public void materialCleaningPackaging(Integer id) {
        MaterialCleaning materialCleaning = getById(id);
        if (materialCleaning.getBatchEnd() == 1){
            throw new RuntimeException("当前批次"+materialCleaning.getProductBatchNo()+"已批次完结，无法再打签成箱！");
        }

        //保存下料记录至MaterialBrokenDetail
        MaterialCleaningDown materialCleaningDown = buildMaterialCleaningDown(materialCleaning);
        materialCleaningDownService.saveOrUpdate(materialCleaningDown);

        //保存打签成箱表至MaterialStoreSignBox
        MaterialStoreSignBox materialStoreSignBox = buildMaterialStoreSignBox(materialCleaningDown);
        materialStoreSignBoxService.saveOrUpdate(materialStoreSignBox);
    }
*/

    /**
     * todo新版原料清洗下料
     *
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Throwable.class)
    public MaterialCleaning materialCleaningPackaging(Integer id) {
        MaterialCleaning materialCleaning = getById(id);
        materialCleaning.setStatus(ItemCleanEnums.MaterialCleanStatus.清洗下料.getKey());
        materialCleaning.setUpdateTime(LocalDateTime.now());
        materialCleaning.setUpdateUser(BaseContextHandler.getUsername());
        materialCleaning.setDownTime(LocalDateTime.now());
        materialCleaning.setDownUser(BaseContextHandler.getUsername());
        materialCleaning.setDownWeight(materialCleaning.getWeight());
        //1 更新清洗表记录
        this.saveOrUpdate(materialCleaning);

        //2 过站(老批次,箱号出站;新批次,箱号进入下一站点)
        cleaningProcessFlowService.outStation(materialCleaning.getProductBatchNo(), materialCleaning.getProductBatchNo(), materialCleaning.getWeight(), BigDecimal.ZERO, materialCleaning.getWeight(), materialCleaning.getDeviceNo(), EnumValuesFactory.CleaningWipStorageCode.清洗.getValue(), "", materialCleaning.getBoxNo(), EnumValuesFactory.CleaningWipStorageCode.清洗.getValue(), EnumValuesFactory.CleaningWipStorageStatus.工序出站.getKey());
        cleaningProcessFlowService.inStation(materialCleaning.getProductBatchNo(), materialCleaning.getProductBatchNo(), materialCleaning.getWeight(), BigDecimal.ZERO, materialCleaning.getWeight(), materialCleaning.getDeviceNo(), EnumValuesFactory.CleaningWipStorageCode.破碎.getValue(), "", materialCleaning.getBoxNo(), EnumValuesFactory.CleaningWipStorageCode.清洗.getValue(), EnumValuesFactory.CleaningWipStorageStatus.工序待进站.getKey());
        return materialCleaning;
    }

    @Override
    public MaterialCleaning getByBatchNo(String batchNo) {
        LambdaQueryWrapper<MaterialCleaning> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialCleaning::getProductBatchNo, batchNo);
        queryWrapper.eq(MaterialCleaning::getBatchEnd, 0);
        queryWrapper.last("limit 1");
        return getOne(queryWrapper);
    }

    @Override
    public List<MaterialCleaningBasket> getBasketInfoByCleanId(Integer id) {
        LambdaQueryWrapper<MaterialCleaningBasket> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialCleaningBasket::getCleanId, id);
        return materialCleaningBasketService.getBaseMapper().selectList(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void markBasket(Integer basketId) {
        MaterialCleaningBasket basket = materialCleaningBasketService.getById(basketId);
        if (basket.getStatus() == 0) {
            basket.setStatus(1);
        } else {
            basket.setStatus(0);
        }
        basket.setUpdateUser(BaseContextHandler.getUsername());
        basket.setUpdateTime(LocalDateTime.now());
        materialCleaningBasketService.saveOrUpdate(basket);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void materialCleaningBasketChoose(MaterialCleaningBasketChooseDto dto) {
        //old存在的花篮号
        List<MaterialCleaningBasket> oldBaskets = materialCleaningBasketService.findByCleanId(dto.getId());
        Map<String, MaterialCleaningBasket> map = oldBaskets.stream().collect(Collectors.toMap(MaterialCleaningBasket::getBasketNo, value -> value));

        Set<String> set = new HashSet<>();
        List<BasketInfoDto> basketInfo = dto.getBasketInfo();
        if (basketInfo != null && basketInfo.size() > 0) {
            //保存dto.getBasketInfo()的花篮,存在了就不保存
            for (BasketInfoDto basketInfoDto : basketInfo) {
                if (!map.containsKey(basketInfoDto.getBasketNo())) {
                    MaterialCleaningBasket newBasket = buildMaterialCleaningBasket(basketInfoDto, dto.getId());
                    materialCleaningBasketService.saveOrUpdate(newBasket);
                }
                set.add(basketInfoDto.getBasketNo());
            }

            //删除掉dto.getBasketInfo()中不存在的花篮
//            for (MaterialCleaningBasket oldBasket : oldBaskets) {
//                if (!set.contains(oldBasket.getBasketNo())) {
//                    materialCleaningBasketService.getBaseMapper().deleteById(oldBasket.getId());
//                }
//            }

        }

    }

    private MaterialStoreSignBox buildMaterialStoreSignBox(MaterialCleaningDown materialCleaningDown) {
        MaterialStoreSignBox materialStoreSignBox = new MaterialStoreSignBox();
//        materialStoreSignBox.setWeight();   //清洗打签成箱没有重量
        materialStoreSignBox.setMaterialBoxNo(materialCleaningDown.getMaterialBoxNo());
        materialStoreSignBox.setProductBatchNo(materialCleaningDown.getProductBatchNo());
        materialStoreSignBox.setMaterialCode(materialCleaningDown.getMaterialCode());
        materialStoreSignBox.setMaterialName(materialCleaningDown.getMaterialName());
        materialStoreSignBox.setMaterialLevel(materialCleaningDown.getMaterialLevel());
        materialStoreSignBox.setMaterialModel(materialCleaningDown.getMaterialModel());
        materialStoreSignBox.setMaterialGear(materialCleaningDown.getMaterialGear());
        materialStoreSignBox.setMaterialType(ItemCleanEnums.MaterialType.清洗料.getKey());
        materialStoreSignBox.setPickingStatus(1);
        materialStoreSignBox.setCreateUser(BaseContextHandler.getUsername());
        materialStoreSignBox.setCreateTime(LocalDateTime.now());
        materialStoreSignBox.setUpdateUser(BaseContextHandler.getUsername());
        materialStoreSignBox.setUpdateTime(LocalDateTime.now());
        return materialStoreSignBox;
    }


    private MaterialCleaningDown buildMaterialCleaningDown(MaterialCleaning materialCleaning) {
        MaterialCleaningDown materialCleaningDown = new MaterialCleaningDown();
//        materialCleaningDown.setWeight();   //清洗打签成箱没有重量
        materialCleaningDown.setProductBatchNo(materialCleaning.getProductBatchNo());
        materialCleaningDown.setMaterialBoxNo(generateBusinessNoService.generateBoxNo(new BoxNoOperate(ItemCleanEnums.BoxNoType.清洗箱号, new MaterialNo(materialCleaning.getMaterialCode()))));
        materialCleaningDown.setMaterialCode(materialCleaning.getMaterialCode());
        materialCleaningDown.setMaterialName(materialCleaning.getMaterialName());
        materialCleaningDown.setMaterialLevel(materialCleaning.getMaterialLevel());
        materialCleaningDown.setMaterialModel(materialCleaning.getMaterialModel());
        materialCleaningDown.setMaterialGear(materialCleaning.getMaterialGear());
        materialCleaningDown.setCleanId(materialCleaning.getId());
        materialCleaningDown.setCreateUser(BaseContextHandler.getUsername());
        materialCleaningDown.setCreateTime(LocalDateTime.now());
        materialCleaningDown.setUpdateUser(BaseContextHandler.getUsername());
        materialCleaningDown.setUpdateTime(LocalDateTime.now());
        return materialCleaningDown;
    }

    private MaterialCleaningBasket buildMaterialCleaningBasket(BasketInfoDto dto, Integer cleanId) {
        MaterialCleaningBasket materialCleaningBasket = new MaterialCleaningBasket();
        materialCleaningBasket.setBasketNo(dto.getBasketNo());
        materialCleaningBasket.setStatus(0);
        materialCleaningBasket.setCleanId(cleanId);
        materialCleaningBasket.setCreateUser(BaseContextHandler.getUsername());
        materialCleaningBasket.setCreateTime(LocalDateTime.now());
        materialCleaningBasket.setUpdateUser(BaseContextHandler.getUsername());
        materialCleaningBasket.setUpdateTime(LocalDateTime.now());
        return materialCleaningBasket;
    }

    private MaterialCleaningDetail buildMaterialCleaningDetail(MaterialCleaningUpDto dto) {
        BoxInfoDto boxInfo = dto.getBoxInfo();
        MaterialStoreSignBox materialStoreSignBox = materialStoreSignBoxService.getByBoxNo(boxInfo.getMaterialBoxNo());
        if (materialStoreSignBox == null) {
            throw new RuntimeException("箱号" + boxInfo.getMaterialBoxNo() + "已上料或不存在");
        }

        MaterialCleaningDetail materialCleaningDetail = new MaterialCleaningDetail();
        materialCleaningDetail.setMaterialBoxNo(boxInfo.getMaterialBoxNo());
        materialCleaningDetail.setWeight(boxInfo.getWeight());
        materialCleaningDetail.setMaterialCode(boxInfo.getMaterialCode());
        materialCleaningDetail.setMaterialName(boxInfo.getMaterialName());
        materialCleaningDetail.setMaterialLevel(boxInfo.getMaterialLevel());
        materialCleaningDetail.setMaterialModel(boxInfo.getMaterialModel());
        materialCleaningDetail.setMaterialGear(boxInfo.getMaterialGear());
        materialCleaningDetail.setProductBatchNo(boxInfo.getProductBatchNo());
        materialCleaningDetail.setCreateUser(BaseContextHandler.getUsername());
        materialCleaningDetail.setCreateTime(LocalDateTime.now());
        materialCleaningDetail.setUpdateUser(BaseContextHandler.getUsername());
        materialCleaningDetail.setUpdateTime(LocalDateTime.now());

        return materialCleaningDetail;
    }

    private MaterialCleaning getMaterialCleaning(MaterialCleaningUpDto dto) {
        MaterialCleaning materialCleaning;
        if (dto.getBoxInfo() != null) {
            //获取批次号清洗任务
            materialCleaning = getByBatchNoAndDevice(dto.getBoxInfo().getProductBatchNo(), dto.getDeviceNo());

            if (materialCleaning != null) {
                BigDecimal nowWeight = Optional.of(materialCleaning).map(MaterialCleaning::getWeight).orElse(new BigDecimal("0"));
                BigDecimal totalWeight = nowWeight.add(dto.getBoxInfo().getWeight());
                materialCleaning.setWeight(totalWeight);
                materialCleaning.setUpdateUser(BaseContextHandler.getUsername());
                materialCleaning.setUpdateTime(LocalDateTime.now());
            } else {
                BoxInfoDto boxInfo = dto.getBoxInfo();
                materialCleaning = new MaterialCleaning();
                materialCleaning.setWeight(boxInfo.getWeight());
                materialCleaning.setMaterialCode(boxInfo.getMaterialCode());
                materialCleaning.setMaterialName(boxInfo.getMaterialName());
                materialCleaning.setMaterialLevel(boxInfo.getMaterialLevel());
                materialCleaning.setMaterialModel(boxInfo.getMaterialModel());
                materialCleaning.setMaterialGear(boxInfo.getMaterialGear());
                materialCleaning.setProductBatchNo(boxInfo.getProductBatchNo());
                materialCleaning.setBatchEnd(0);
                materialCleaning.setDeviceNo(dto.getDeviceNo());
                materialCleaning.setCreateUser(BaseContextHandler.getUsername());
                materialCleaning.setCreateTime(LocalDateTime.now());
                materialCleaning.setUpdateUser(BaseContextHandler.getUsername());
                materialCleaning.setUpdateTime(LocalDateTime.now());
            }
            return materialCleaning;
        } else {
            throw new RuntimeException("上料信息缺失！");
        }
    }

    public MaterialCleaning getByBatchNoAndDevice(String batchNo, String deviceNo) {
        LambdaQueryWrapper<MaterialCleaning> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialCleaning::getProductBatchNo, batchNo);
        queryWrapper.eq(MaterialCleaning::getDeviceNo, deviceNo);
        queryWrapper.eq(MaterialCleaning::getBatchEnd, 0);
        queryWrapper.last("limit 1");
        return getOne(queryWrapper);
    }

    @Override
    public List<MaterialCleaning> getByDevice(String deviceNo) {
        LambdaQueryWrapper<MaterialCleaning> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialCleaning::getDeviceNo, deviceNo);
        queryWrapper.eq(MaterialCleaning::getBatchEnd, 0);
        return getBaseMapper().selectList(queryWrapper);
    }

    @Override
    public MaterialCleaning getByBoxNo(String boxNo) {
        LambdaQueryWrapper<MaterialCleaning> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialCleaning::getBoxNo, boxNo);
        queryWrapper.eq(MaterialCleaning::getDelFlag, ItemCleanEnums.MaterialDelFlag.未删除.getKey());
        queryWrapper.eq(MaterialCleaning::getStatus, ItemCleanEnums.MaterialCleanStatus.清洗上料.getKey());
        queryWrapper.orderByDesc(MaterialCleaning::getCreateTime);
        queryWrapper.last("limit 1");
        return this.getOne(queryWrapper);
    }

    @Override
    public PackingBoxInfoPrintDto materialCleaningPackagingBox(MaterialCleaningToBoxDto dto) {

        // 1 新增拆花篮装料信息,过站
        List<BasketInfoDto> basketInfo = dto.getBasketInfo();
        MaterialCleaning materialCleaning = new MaterialCleaning();
        materialCleaning.setStatus(0);
        materialCleaning.setBoxNo(dto.getBoxNo());
        materialCleaning.setBoxWeight(dto.getBoxWeight());
        materialCleaning.setTypeName(dto.getTypeName());
        materialCleaning.setPreBoxNo("");
        materialCleaning.setWeight(dto.getTotalWeight());
        materialCleaning.setMaterialCode(dto.getMaterialCode());
        materialCleaning.setMaterialName(dto.getMaterialName());
        materialCleaning.setMaterialLevel(dto.getMaterialLevel());
        materialCleaning.setMaterialModel(dto.getMaterialModel());
        materialCleaning.setMaterialGear(dto.getMaterialGear());
        materialCleaning.setProductBatchNo(dto.getProductBatchNo());
        String cleanProductBatchNo = generateBusinessNoService.generateBoxNoForBasketBox(dto.getProductBatchNo(), BASKET_MARK);
        materialCleaning.setCleanProductBatchNo(cleanProductBatchNo);
        materialCleaning.setBatchEnd(0);
        materialCleaning.setDeviceNo(dto.getDeviceNo());
        materialCleaning.setCreateUser(BaseContextHandler.getUsername());
        materialCleaning.setCreateTime(LocalDateTime.now());
        materialCleaning.setUpdateUser(BaseContextHandler.getUsername());
        materialCleaning.setUpdateTime(LocalDateTime.now());
        saveOrUpdate(materialCleaning);
        //新箱过站
        cleaningProcessFlowService.inStation(materialCleaning.getCleanProductBatchNo(), materialCleaning.getProductBatchNo(), materialCleaning.getWeight(), materialCleaning.getWeight(), BigDecimal.ZERO, materialCleaning.getDeviceNo(), EnumValuesFactory.CleaningWipStorageCode.破碎.getValue(), "", materialCleaning.getBoxNo(), EnumValuesFactory.CleaningWipStorageCode.清洗.getValue(), EnumValuesFactory.CleaningWipStorageStatus.工序待进站.getKey());

        // 2.1 更新对应花篮父id和状态
        // 2.1 花篮使用状态变更为未使用
        for (BasketInfoDto basket : basketInfo
        ) {
            LambdaUpdateWrapper<MaterialCleaning> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.set(MaterialCleaning::getStatus, 2)
                    .set(MaterialCleaning::getParentId,materialCleaning.getId() )
                    .set(MaterialCleaning::getUpdateTime, LocalDateTime.now())
                    .set(MaterialCleaning::getUpdateUser, BaseContextHandler.getUsername())
                    .eq(MaterialCleaning::getId, basket.getId());
            this.update(updateWrapper);
            CarrierConfigDto carrierConfigDto = new CarrierConfigDto();
            carrierConfigDto.setCarrierNo(basket.getBasketNo());
            carrierConfigDto.setStatus(0);
            ybFeignClients.updateCarrierConfigStatus(carrierConfigDto);
        }

        //3 装箱载具使用状态变更为使用中
        CarrierConfigDto newCarrierConfigDto = new CarrierConfigDto();
        newCarrierConfigDto.setCarrierNo(dto.getBoxNo());
        newCarrierConfigDto.setStatus(1);
        ybFeignClients.updateCarrierConfigStatus(newCarrierConfigDto);

        //4 返回花篮成箱打印信息
        PackingBoxInfoPrintDto packingBoxInfoPrintDto = buildPackingBoxInfoPrintDto(materialCleaning);
        return packingBoxInfoPrintDto;
    }

    /**
     * 破碎上料前置触发清洗下料
     *
     * @param basketNo
     */
    @Override
    public MaterialCleaning materialCleaningPackagingByBoxNo(String basketNo) {
        MaterialCleaning cleaning = getByBoxNo(basketNo);
        if (null == cleaning) {
            throw new BusinessException(basketNo + ":花篮中无数据");
        }
        //清洗下料
        return materialCleaningPackaging(cleaning.getId());
    }

    @Override
    public MaterialCleaning getNotCleanByBoxNo(String boxNo) {
        LambdaQueryWrapper<MaterialCleaning> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialCleaning::getBoxNo, boxNo);
        queryWrapper.eq(MaterialCleaning::getDelFlag, ItemCleanEnums.MaterialDelFlag.未删除.getKey());
        queryWrapper.in(MaterialCleaning::getStatus, ItemCleanEnums.MaterialCleanStatus.清洗上料.getKey(), ItemCleanEnums.MaterialCleanStatus.清洗下料.getKey());
        queryWrapper.orderByDesc(MaterialCleaning::getCreateTime);
        queryWrapper.last("limit 1");
        return this.getOne(queryWrapper);
    }

    /**
     * 构建花篮成箱打签数据
     * @param materialCleaning
     * @return
     */
    public PackingBoxInfoPrintDto buildPackingBoxInfoPrintDto(MaterialCleaning materialCleaning) {
        // 查询物料编码所属厂家
        Result<MaterialCleanModelDto> result = ybFeignClients.findMaterialCleanByCode(materialCleaning.getMaterialCode());
        if (!result.getCode().equals(ResultCode.SUCCESS.code)) {
            throw new RuntimeException("查询原料清洗产品模型发生错误");
        }
        MaterialCleanModelDto dto = result.getData();
        if (dto == null) {
            throw new RuntimeException("不存在" + materialCleaning.getMaterialCode() + "原料清洗产品模型！");
        }
        PackingBoxInfoPrintDto packingBoxInfoPrintDto = new PackingBoxInfoPrintDto();
        packingBoxInfoPrintDto.setBoxNo(materialCleaning.getBoxNo())
                .setCurrentProductBatchNo(materialCleaning.getCleanProductBatchNo())
                .setCreateTime(new Date())
                .setDeviceNo(materialCleaning.getDeviceNo())
                .setFromMark(dto.getFactoryCode())
                .setClassNoName(BaseContextHandler.getUserClassNo())
                .setMaterialName(materialCleaning.getMaterialName())
                .setMaterialModel(materialCleaning.getMaterialModel())
                .setWeight(String.valueOf(materialCleaning.getWeight()))
                .setMaterialGear(materialCleaning.getMaterialGear())
                .setMaterialLevel(materialCleaning.getMaterialLevel())
                .setRemark("");
        return packingBoxInfoPrintDto;
    }
}
