package com.prolog.eis.service.page.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.prolog.cs.basic.item.model.vo.ItemBaseInfoVO;
import com.prolog.eis.common.util.PrologStringUtils;
import com.prolog.eis.constants.base.ContainerTaskStatusConstants;
import com.prolog.eis.constants.base.OrderStatusConstants;
import com.prolog.eis.constants.sys.SysParamConstants;
import com.prolog.eis.constants.wms.WmsConstants;
import com.prolog.eis.dao.SysParamMapper;
import com.prolog.eis.dao.container.ContainerInfoDetailMapper;
import com.prolog.eis.dao.container.ContainerInfoMapper;
import com.prolog.eis.dao.container.ContainerTaskMapper;
import com.prolog.eis.dao.outbound.BizOutboundTaskDetailMapper;
import com.prolog.eis.dao.outbound.BizOutboundTaskMapper;
import com.prolog.eis.dao.pick.PickingOrderMapper;
import com.prolog.eis.dto.item.ItemSyncVO;
import com.prolog.eis.dto.outbound.PagePriorityDto;
import com.prolog.eis.dto.outbound.PriorityDto;
import com.prolog.eis.dto.page.*;
import com.prolog.eis.enums.base.BaseStatusEnum;
import com.prolog.eis.model.container.ContainerInfoDetail;
import com.prolog.eis.model.container.ContainerTask;
import com.prolog.eis.model.inbound.BizInboundTaskDetail;
import com.prolog.eis.model.outbound.BizOutboundTask;
import com.prolog.eis.model.pick.PickingOrder;
import com.prolog.eis.model.sys.SysParam;
import com.prolog.eis.service.feign.FeignGoodsService;
import com.prolog.eis.service.inbound.BizInboundTaskDetailService;
import com.prolog.eis.service.inbound.BizInboundTaskService;
import com.prolog.eis.service.inbound.InventoryService;
import com.prolog.eis.service.page.PageService;
import com.prolog.eis.service.sys.SysParamService;
import com.prolog.eis.service.wms.WmsItemPageService;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.BizException;
import com.prolog.framework.core.exception.PrologException;
import com.prolog.framework.core.pojo.Page;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.dao.util.PageUtils;
import com.prolog.framework.utils.AssertUtils;
import com.prolog.framework.utils.MapUtils;
import com.prolog.framework.utils.ObjectUtils;
import com.prolog.framework.utils.StringUtils;
import com.prolog.upcloud.base.inventory.model.BatchNumberSync;
import com.prolog.upcloud.base.inventory.model.WmsInvBatchNumbers;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class PageServiceImpl implements PageService {

    private final BizOutboundTaskMapper bizOutboundTaskMapper;
    private final BizOutboundTaskDetailMapper bizOutboundTaskDetailMapper;
    private final SysParamService sysParamService;
    private final SysParamMapper sysParamMapper;
    private final PickingOrderMapper pickingOrderMapper;
    private final ContainerInfoMapper containerInfoMapper;
    private final BizInboundTaskService bizInboundTaskService;
    private final FeignGoodsService feignGoodsService;
    private final BizInboundTaskDetailService bizInboundTaskDetailService;
    private final InventoryService inventoryService;
    private final WmsItemPageService wmsItemPageService;
    private final ContainerInfoDetailMapper containerInfoDetailMapper;
    private final ContainerTaskMapper containerTaskMapper;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestMessage<String> updateTaskPriority(List<OutQueryDto> dtoList) {
        List<PriorityDto> errorList = Lists.newArrayList();
        StringBuilder errors = new StringBuilder("请求部分失败:");
        boolean flag = true;
        for (OutQueryDto dto : dtoList) {
            BizOutboundTask outboundTask = bizOutboundTaskMapper.findById(dto.getId(), BizOutboundTask.class);
            if (ObjectUtils.isNull(outboundTask)) {
                errors.append(dto.getBillNo() + "订单出库任务不存在");
                flag = false;
                continue;
            }
            if (0 != outboundTask.getStatus()) {
                errors.append(dto.getBillNo() + "订单当前出库任务状态不支持调整优先级,");
                flag = false;
                continue;
            }
            if (dto.getNewPriority() == null) {
                throw new BizException("新优先级不能为空");
            }
            if (dto.getNewPriority().compareTo(WmsConstants.MAX_PRIORITY_99) > 0
                    || dto.getNewPriority().compareTo(WmsConstants.MIN_PRIORITY_0) < 0) {
                throw new BizException("优先级范围：0-99");
            }
            bizOutboundTaskMapper.updateMapById(dto.getId(),
                    MapUtils.put("priority", dto.getNewPriority()).put("updateTime", LocalDateTime.now()).getMap(),
                    BizOutboundTask.class);
        }
        if (flag) {
            return RestMessage.newInstance(true, "请求成功");
        }
        return RestMessage.newInstance(false, "500", errors.substring(0, errors.length() - 1).toString(), null);
    }

    @Override
    public void updateTaskType(AssemblyStateDto req) {
        Object key = SysParamConstants.ASSEMBLY_TYPE_MAP.get(req.getType());
        AssertUtils.isNotNull(key, "类型错误");
        Long l = sysParamService.updateSysParam(key.toString(), req.getState().toString());
        AssertUtils.isTrue(l > 0, "更新失败");
    }

    @Override
    public void groupOrderDistribute(List<Integer> outboundTaskIds) {
        List<SysParam> sysParamList = sysParamMapper.findByMap(MapUtils.put("paramNo", SysParamConstants.ASSEMBLY_ORDER_SWITCH).put("paramValue", SysParamConstants.ASSEMBLY_ORDER_SWITCH_OFF).getMap(), SysParam.class);
        /**
         * 校验开关
         */
        if (CollectionUtils.isEmpty(sysParamList)) {
            throw new BizException("组单调度开关不是关闭");
        }
        /**
         * 校验传过来的list下的每个对象是不是都存在
         */
        List<BizOutboundTask> outboundTasks = bizOutboundTaskMapper.findByIds(BizOutboundTask.class, outboundTaskIds.toArray(), null);

        if (CollectionUtils.isEmpty(outboundTasks)) {
            throw new BizException("订单不存在");
        }
        List<Integer> taskIds = outboundTasks.stream().map(BizOutboundTask::getId).collect(Collectors.toList());

        if (!taskIds.containsAll(outboundTaskIds)) {
            outboundTaskIds.removeAll(taskIds);
            throw new BizException(outboundTaskIds + "订单不存在");
        }
        /**
         * 看看是不是存在除了为0（创建）之外的状态，只有创建的才能下发
         */
        List<BizOutboundTask> bizOutboundTasks = outboundTasks.stream().filter(item -> item.getStatus() != 0).collect(Collectors.toList());

        if (!CollectionUtils.isEmpty(bizOutboundTasks)) {
            throw new BizException("只有创建的订单才能下发");
        }

        for (BizOutboundTask outboundTask : outboundTasks) {
            outboundTask.setEisWaveNo(PrologStringUtils.newGUID());
            bizOutboundTaskMapper.update(outboundTask);
        }

    }

    @Override
    public String assemblyState(String type) {
        Object key = SysParamConstants.ASSEMBLY_TYPE_MAP.get(type);
        AssertUtils.isNotNull(key, "类型错误");
        SysParam sysParam = sysParamMapper.findByMap(MapUtils.put("paramNo", key.toString()).getMap(), SysParam.class).stream().findFirst().orElseThrow(() -> new PrologException("自动组单开关参数未配置"));
        return sysParam.getParamValue();
    }

    @Override
    public OrderNumDto orderNum() {
        final long totalNum = bizOutboundTaskMapper.findCountByMap(null, BizOutboundTask.class);
        final long readyNum = bizOutboundTaskMapper.findCountByMap(MapUtils.put("status", OrderStatusConstants.INIT_STATUS).getMap(), BizOutboundTask.class);
        final long finishNum = bizOutboundTaskMapper.findCountByMap(MapUtils.put("status", OrderStatusConstants.FINISH_STATUS).getMap(), BizOutboundTask.class);
        return OrderNumDto.builder()
                .totalNum(totalNum)
                .readyNum(readyNum)
                .finishNum(finishNum)
                .build();
    }

    @Override
    public List<PickingOrderRespDto> pickingOrderList(PickingOrderReqDto req) {
        return pickingOrderMapper.listPage(req);
    }

    @Override
    public List<PickingOutboundOrderRespDto> pickOutboundOrderList(Integer packId) {
        List<BizOutboundTask> outboundTaskList = bizOutboundTaskMapper.findByMap(MapUtils.put("pickOrderId", packId).getMap(), BizOutboundTask.class);
        List<PickingOutboundOrderRespDto> resultList = new ArrayList<>();
        outboundTaskList.forEach(item -> {
            resultList.add(PickingOutboundOrderRespDto.builder()
                    .id(item.getId())
                    .type(item.getBillType())
                    .billNo(item.getBillNo())
                    //.productCode(item.getProductCode())
                    .status(item.getStatus())
                    .isLack(item.isLack()).build());
        });
        return resultList;
    }


    @Override
    public void pickOrderLock(PickOrderLockReqDto req) {
        PickingOrder pickingOrder = pickingOrderMapper.findById(req.getPickId(), PickingOrder.class);
        AssertUtils.isNotNull(pickingOrder, "查询到的组单为空");
        AssertUtils.isTrue(pickingOrder.getStatus().equals(BaseStatusEnum.STATUS_INIT.getCode()), "此组单已开始无法控制暂停继续");
        AssertUtils.isNotTrue(pickingOrder.getIsLock().equals(req.getType()), String.format("此组单已是%s状态", req.getTypeMsg()));
        pickingOrder.setIsLock(req.getType());
        pickingOrder.setUpdateTime(LocalDateTime.now());
        pickingOrderMapper.update(pickingOrder);
    }

    @Override
    @Transactional
    public void outboundOrderCancel(List<Integer> ids) {
        Criteria criteria = new Criteria(BizOutboundTask.class);
        criteria.restrictionBuilder().in(BizOutboundTask::getId, ids).build();
        List<BizOutboundTask> bizOutboundTaskList = bizOutboundTaskMapper.findByCriteria(criteria);
        for (BizOutboundTask outboundTask : bizOutboundTaskList) {
            AssertUtils.isTrue(outboundTask.getStatus().equals(BaseStatusEnum.STATUS_INIT.getCode()), String.format("单据【%s】状态不支持取消", outboundTask.getBillNo()));
            outboundTask.setStatus(BaseStatusEnum.STATUS_FAIL.getCode());
            outboundTask.setUpdateTime(LocalDateTime.now());
            bizOutboundTaskMapper.update(outboundTask);
        }
    }

    @Override
    public void pickOrderActive(List<Integer> ids) {
        SysParam sysParam = sysParamMapper.findByMap(MapUtils.put("paramNo", SysParamConstants.ASSEMBLY_PACKAGE_SWITCH).getMap(), SysParam.class).stream().findFirst().orElseThrow(() -> new PrologException("自动组单开关参数未配置"));
        AssertUtils.isNotTrue(sysParam.getParamValue().equals("1"), "组单已开启不支持手动激活");
        Criteria criteria = new Criteria(PickingOrder.class);
        criteria.restrictionBuilder().in(PickingOrder::getId, ids).build();
        pickingOrderMapper.updateMapByCriteria(MapUtils.put("isLock", 0).getMap(), criteria);
    }

    @Override
    public Object itemList(ItemReqDto req) throws Exception {
        RestMessage restMessage = wmsItemPageService.execute(req);
        return restMessage.getData();
    }

    @Override
    public Page<LockStockRespDto> lockStockListPage(LockStockReqDto req) throws Exception {
        List<String> itemIds = new ArrayList<>();
        List<String> lotIds = new ArrayList<>();
        if(!StringUtils.isEmpty(req.getItemName())){
            List<ItemBaseInfoVO> itemList = feignGoodsService.getItemByName(req.getItemName());
            if (CollectionUtils.isNotEmpty(itemList)) {
                List<String> itemIdList = itemList.stream().map(ItemBaseInfoVO::getItemId).distinct().collect(Collectors.toList());
                itemIds.addAll(itemIdList);
            }
        }
        if(!StringUtils.isEmpty(req.getLotNo())){
            List<WmsInvBatchNumbers> listByManufacturerLotNums = inventoryService.getListByManufacturerLotNums(req.getLotNo());
            List<String> LotIdList = listByManufacturerLotNums.stream().map(WmsInvBatchNumbers :: getBatchId).collect(Collectors.toList());
            lotIds.addAll(LotIdList);
        }
        PageUtils.startPage(req.getPageNum(), req.getPageSize());
        List<LockStockRespDto> lockStockRespDtos = containerInfoMapper.lockStockListPage(itemIds, lotIds, req.getContainerNo(), req.getIsLock());
        List<String> itemIdsResp = lockStockRespDtos.stream().map(LockStockRespDto::getItemId).collect(Collectors.toList());
        List<String> lotIdsResp = lockStockRespDtos.stream().map(LockStockRespDto::getLotId).collect(Collectors.toList());
        List<ItemSyncVO> itemInfoList = feignGoodsService.queryItemMst(itemIdsResp);
//        List<BatchNumberSync> batchNumberSync = inventoryService.getBatchNumberSync(lotIdsResp);

        for (LockStockRespDto item : lockStockRespDtos) {
            ItemSyncVO itemSyncVO = itemInfoList.stream().filter(inner -> inner.getItemId().equals(item.getItemId())).findFirst().orElseThrow(() -> new PrologException("为查询到商品信息"));
//            BatchNumberSync numberSync = batchNumberSync.stream().filter(inner -> inner.getBatchId().equals(item.getLotId())).findFirst().orElseThrow(() -> new PrologException("为查询到批次信息"));
            item.setItemName(itemSyncVO.getItemName());
            item.setItemCode(itemSyncVO.getItemCode());
//            item.setLotCode(numberSync.getManufacturerLotNum());
            item.setLotCode("11111");
        }
        return PageUtils.getPage(lockStockRespDtos);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized void lockContainerStocks(List<String> containerSubNos) throws Exception {
        if(CollectionUtils.isEmpty(containerSubNos)){
            throw new BizException("容器编号不能为空");
        }
        Criteria c1 = Criteria.forClass(ContainerInfoDetail.class);
        c1.restrictionBuilder().in(ContainerInfoDetail::getContainerSubNo, containerSubNos).build();
        List<ContainerInfoDetail> containerInfoDetails = containerInfoDetailMapper.findByCriteria(c1);

        Criteria c2 = Criteria.forClass(ContainerTask.class);
        c2.restrictionBuilder().in(ContainerTask :: getContainerSubNo, containerSubNos)
                .le(ContainerTask :: getStatus, ContainerTaskStatusConstants.IN_PLACE_STATUS)
                .build();
        List<ContainerTask> containerTasks = containerTaskMapper.findByCriteria(c2);
        // 容器任务按照子容器号进行分组
        Map<String, List<ContainerTask>> containerMap = containerTasks.stream().collect(Collectors.groupingBy(ContainerTask::getContainerSubNo));

        for (ContainerInfoDetail containerInfoDetail : containerInfoDetails) {
            if(containerMap.containsKey(containerInfoDetail.getContainerSubNo())){
                BigDecimal sumQty = containerMap.get(containerInfoDetail.getContainerSubNo()).stream().map(ContainerTask::getQty).reduce(BigDecimal.ZERO, BigDecimal::add);
                containerInfoDetail.setLockQty(containerInfoDetail.getQty().subtract(sumQty));
            }else{
                containerInfoDetail.setLockQty(containerInfoDetail.getQty());
            }
        }
        for(ContainerInfoDetail containerInfoDetail : containerInfoDetails){
            containerInfoDetailMapper.updateMapById(containerInfoDetail.getId(),MapUtils.put("lockQty",containerInfoDetail.getLockQty()).getMap(),ContainerInfoDetail.class);
        }

    }

    @Override
    public void lockContainerStock(String containerNo, BigDecimal lockQty) throws Exception {
        if(StringUtils.isEmpty(containerNo)){
            throw new BizException("容器编号不能为空！");
        }
        if(ObjectUtils.isNull(lockQty)){
            throw new BizException("锁定库存数量不能为空！");
        }
        if(lockQty.compareTo(BigDecimal.ZERO) <= 0){
            throw new BizException("锁定库存数量必须大于0！");
        }
        synchronized (containerNo.intern()){
            Criteria c1 = Criteria.forClass(ContainerInfoDetail.class);
            c1.restrictionBuilder().eq(ContainerInfoDetail::getContainerSubNo, containerNo).build();
            List<ContainerInfoDetail> containerInfoDetails = containerInfoDetailMapper.findByCriteria(c1);

            Criteria c2 = Criteria.forClass(ContainerTask.class);
            c2.restrictionBuilder().eq(ContainerTask::getContainerSubNo, containerNo).build();
            List<ContainerTask> containerTasks = containerTaskMapper.findByCriteria(c2);
            BigDecimal sumQty = containerTasks.stream().map(ContainerTask::getQty).reduce(BigDecimal.ZERO, BigDecimal::add);
            if(CollectionUtils.isEmpty(containerInfoDetails)){
                throw new BizException("容器库存不存在！");
            }
            ContainerInfoDetail containerInfoDetail = containerInfoDetails.get(0);
            if(containerInfoDetail.getQty().subtract(sumQty).subtract(containerInfoDetail.getLockQty()).compareTo(BigDecimal.ZERO) <= 0){
                throw new BizException("锁定库存数量不能大于库存数量！");
            }
            containerInfoDetail.setLockQty(containerInfoDetail.getLockQty().add(lockQty));
            containerInfoDetailMapper.updateMapById(containerInfoDetail.getId(),MapUtils.put("lockQty",containerInfoDetail.getLockQty()).getMap(),ContainerInfoDetail.class);
        }
    }

    @Override
    public LockStockRespDto lockContainerStockDetail(String containerNo) throws Exception {
        if(StringUtils.isEmpty(containerNo)){
            throw new BizException("容器编号不能为空！");
        }
        List<LockStockRespDto> lockStockRespDtos = containerInfoMapper.lockStockListPage(null, null, containerNo, null);
        List<String> itemIdsResp = lockStockRespDtos.stream().map(LockStockRespDto::getItemId).collect(Collectors.toList());
//        List<String> lotIdsResp = lockStockRespDtos.stream().map(LockStockRespDto::getLotId).collect(Collectors.toList());
        List<ItemSyncVO> itemInfoList = feignGoodsService.queryItemMst(itemIdsResp);
//        List<BatchNumberSync> batchNumberSync = inventoryService.getBatchNumberSync(lotIdsResp);

        for (LockStockRespDto item : lockStockRespDtos) {
            ItemSyncVO itemSyncVO = itemInfoList.stream().filter(inner -> inner.getItemId().equals(item.getItemId())).findFirst().orElseThrow(() -> new PrologException("为查询到商品信息"));
//            BatchNumberSync numberSync = batchNumberSync.stream().filter(inner -> inner.getBatchId().equals(item.getLotId())).findFirst().orElseThrow(() -> new PrologException("为查询到批次信息"));
            item.setItemName(itemSyncVO.getItemName());
            item.setItemCode(itemSyncVO.getItemCode());
//            item.setLotCode(numberSync.getManufacturerLotNum());
            item.setLotCode("11111");
        }
        return lockStockRespDtos.isEmpty() ? null : lockStockRespDtos.get(0);
    }

    @Override
    public void unLockContainerStock(List<String> containerSubNos) throws Exception {
        if(CollectionUtils.isEmpty(containerSubNos)){
            throw new BizException("容器编号不能为空");
        }
        Criteria c1 = Criteria.forClass(ContainerInfoDetail.class);
        c1.restrictionBuilder().in(ContainerInfoDetail::getContainerSubNo, containerSubNos).build();
        containerInfoDetailMapper.updateMapByCriteria(MapUtils.put("lockQty", BigDecimal.ZERO).getMap(), c1);

    }

    @Override
    public List<OutboundOrderRespDto> outboundOrderList(PickingOrderReqDto req) {
        List<String> itemIds = new ArrayList<>();
        if (StrUtil.isNotBlank(req.getItemId())) {
            itemIds.add(req.getItemId());
        } else {
            if (StrUtil.isNotBlank(req.getItemName())) {
                List<ItemBaseInfoVO> itemList = feignGoodsService.getItemByName(req.getItemName());
                if (CollectionUtils.isNotEmpty(itemList)) {
                    List<String> itemIdList = itemList.stream().map(ItemBaseInfoVO::getItemId).distinct().collect(Collectors.toList());
                    itemIds.addAll(itemIdList);
                }
            }
            if (StrUtil.isNotBlank(req.getItemCode())) {
                List<ItemSyncVO> itemList = feignGoodsService.getItemByBarcode(req.getItemCode());
                if (CollectionUtils.isNotEmpty(itemList)) {
                    List<String> itemIdList = itemList.stream().map(ItemSyncVO::getItemId).distinct().collect(Collectors.toList());
                    itemIds.addAll(itemIdList);
                }
            }
            if (StrUtil.isNotBlank(req.getItemBarCode())) {
                List<ItemSyncVO> itemList = feignGoodsService.getItemByBarcode(req.getItemBarCode());
                if (CollectionUtils.isNotEmpty(itemList)) {
                    List<String> itemIdList = itemList.stream().map(ItemSyncVO::getItemId).distinct().collect(Collectors.toList());
                    itemIds.addAll(itemIdList);
                }
            }
        }
        if (CollectionUtil.isNotEmpty(itemIds)) {
            req.setItemIds(itemIds);
        }
        PageUtils.startPage(req.getPageNum(), req.getPageSize());
        List<OutboundOrderRespDto> list = bizOutboundTaskMapper.outboundOrderList(req);
        return list;
    }

    @Override
    public List<OutboundOrderDetailRespDto> orderDetailList(Integer id) throws Exception {
        final List<OutboundOrderDetailRespDto> outboundOrderDetailRespDtoList = bizOutboundTaskDetailMapper.detailList(id);
        final List<String> itemIds = outboundOrderDetailRespDtoList.stream().map(OutboundOrderDetailRespDto::getItemId).collect(Collectors.toList());
        final List<String> lotIds = outboundOrderDetailRespDtoList.stream().map(OutboundOrderDetailRespDto::getLotId).collect(Collectors.toList());
        final List<ItemSyncVO> itemInfoList = feignGoodsService.queryItemMst(itemIds);
        List<BatchNumberSync> batchNumberSync = inventoryService.getBatchNumberSync(lotIds);
        for (OutboundOrderDetailRespDto item : outboundOrderDetailRespDtoList) {
            ItemSyncVO itemSyncVO = itemInfoList.stream().filter(inner -> inner.getItemId().equals(item.getItemId())).findFirst().orElseThrow(() -> new PrologException("为查询到商品信息"));
            BatchNumberSync numberSync = batchNumberSync.stream().filter(inner -> inner.getBatchId().equals(item.getLotId())).findFirst().orElseThrow(() -> new PrologException("为查询到批次信息"));
            item.setItemName(itemSyncVO.getItemName());
            item.setItemCode(itemSyncVO.getItemCode());
            item.setLotId(numberSync.getManufacturerLotNum());
        }
        return outboundOrderDetailRespDtoList;
    }

    @Override
    public List<OrderStockWarnRespDto> orderStockWarn(OrderStockWarnReqDto req) throws Exception {
        if (StrUtil.isNotBlank(req.getItemName()) && StrUtil.isNotBlank(req.getItemCode())) {
            List<ItemBaseInfoVO> itemInfoList = feignGoodsService.getItemByName(req.getItemName());
            List<ItemSyncVO> itemByBarcode = feignGoodsService.getItemByBarcode(req.getItemCode());
            if (CollectionUtils.isEmpty(itemInfoList) && CollectionUtils.isEmpty(itemByBarcode)) {
                req.setItemIds("-1");
            } else if (CollectionUtils.isNotEmpty(itemInfoList) && CollectionUtils.isNotEmpty(itemByBarcode)) {
                List<String> itemIds1 = itemInfoList.stream().map(ItemBaseInfoVO::getItemId).collect(Collectors.toList());
                List<String> itemIds2 = itemByBarcode.stream().map(ItemSyncVO::getItemId).collect(Collectors.toList());
                itemIds1.retainAll(itemIds2);
                req.setItemIds(StrUtil.join(",", itemIds1));
            } else if (CollectionUtils.isNotEmpty(itemInfoList)) {
                List<String> itemIds1 = itemInfoList.stream().map(ItemBaseInfoVO::getItemId).collect(Collectors.toList());
                req.setItemIds(StrUtil.join(",", itemIds1));
            } else if (CollectionUtils.isNotEmpty(itemByBarcode)) {
                List<String> itemIds2 = itemByBarcode.stream().map(ItemSyncVO::getItemId).collect(Collectors.toList());
                req.setItemIds(StrUtil.join(",", itemIds2));
            }
        } else if (StrUtil.isNotBlank(req.getItemName())) {
            List<ItemBaseInfoVO> itemInfoList = feignGoodsService.getItemByName(req.getItemName());
            List<String> itemIds = itemInfoList.stream().map(ItemBaseInfoVO::getItemId).collect(Collectors.toList());
            req.setItemIds(StrUtil.join(",", itemIds));
        } else if (StrUtil.isNotBlank(req.getItemCode())) {
            List<ItemSyncVO> itemByBarcode = feignGoodsService.getItemByBarcode(req.getItemCode());
            List<String> itemIds = itemByBarcode.stream().map(ItemSyncVO::getItemId).collect(Collectors.toList());
            req.setItemIds(StrUtil.join(",", itemIds));
        }
        List<OrderStockWarnRespDto> orderStockWarnRespDtos = bizOutboundTaskDetailMapper.orderStockWarn(req);
        final List<String> itemIds = orderStockWarnRespDtos.stream().map(OrderStockWarnRespDto::getItemId).collect(Collectors.toList());
        final List<String> lotIds = orderStockWarnRespDtos.stream().map(OrderStockWarnRespDto::getLotId).collect(Collectors.toList());
        final List<ItemSyncVO> itemInfoList = feignGoodsService.queryItemMst(itemIds);
        List<BatchNumberSync> batchNumberSync = inventoryService.getBatchNumberSync(lotIds);
        for (OrderStockWarnRespDto item : orderStockWarnRespDtos) {
            ItemSyncVO itemSyncVO = itemInfoList.stream().filter(inner -> inner.getItemId().equals(item.getItemId())).findFirst().orElseThrow(() -> new PrologException("为查询到商品信息"));
            BatchNumberSync numberSync = batchNumberSync.stream().filter(inner -> inner.getBatchId().equals(item.getLotId())).findFirst().orElseThrow(() -> new PrologException("为查询到批次信息"));
            item.setItemName(itemSyncVO.getItemName());
            item.setItemCode(itemSyncVO.getItemCode());
            item.setBarCode(itemSyncVO.getPieceBarcode());
            item.setLotId(numberSync.getBatchNum());
        }
        return orderStockWarnRespDtos;
    }

    @Override
    public List<StockRespDto> stockList(StockReqDto req) throws Exception {
        if (StrUtil.isNotBlank(req.getItemName()) && StrUtil.isNotBlank(req.getItemCode())) {
            List<ItemBaseInfoVO> itemInfoList = feignGoodsService.getItemByName(req.getItemName());
            List<ItemSyncVO> itemByBarcode = feignGoodsService.getItemByBarcode(req.getItemCode());
            if (CollectionUtils.isEmpty(itemInfoList) && CollectionUtils.isEmpty(itemByBarcode)) {
                req.setItemIds("-1");
            } else if (CollectionUtils.isNotEmpty(itemInfoList) && CollectionUtils.isNotEmpty(itemByBarcode)) {
                List<String> itemIds1 = itemInfoList.stream().map(ItemBaseInfoVO::getItemId).collect(Collectors.toList());
                List<String> itemIds2 = itemByBarcode.stream().map(ItemSyncVO::getItemId).collect(Collectors.toList());
                itemIds1.retainAll(itemIds2);
                req.setItemIds(StrUtil.join(",", itemIds1));
            } else if (CollectionUtils.isNotEmpty(itemInfoList)) {
                List<String> itemIds1 = itemInfoList.stream().map(ItemBaseInfoVO::getItemId).collect(Collectors.toList());
                req.setItemIds(StrUtil.join(",", itemIds1));
            } else if (CollectionUtils.isNotEmpty(itemByBarcode)) {
                List<String> itemIds2 = itemByBarcode.stream().map(ItemSyncVO::getItemId).collect(Collectors.toList());
                req.setItemIds(StrUtil.join(",", itemIds2));
            }
        } else if (StrUtil.isNotBlank(req.getItemName())) {
            List<ItemBaseInfoVO> itemInfoList = feignGoodsService.getItemByName(req.getItemName());
            List<String> itemIds = itemInfoList.stream().map(ItemBaseInfoVO::getItemId).collect(Collectors.toList());
            req.setItemIds(StrUtil.join(",", itemIds));
        } else if (StrUtil.isNotBlank(req.getItemCode())) {
            List<ItemSyncVO> itemByBarcode = feignGoodsService.getItemByBarcode(req.getItemCode());
            List<String> itemIds = itemByBarcode.stream().map(ItemSyncVO::getItemId).collect(Collectors.toList());
            req.setItemIds(StrUtil.join(",", itemIds));
        }
        final List<StockRespDto> stockRespDtos = containerInfoMapper.stockList(req);
        final List<String> itemIds = stockRespDtos.stream().map(StockRespDto::getItemId).collect(Collectors.toList());
        final List<ItemSyncVO> itemSyncVOS = feignGoodsService.queryItemMst(itemIds);
        for (StockRespDto stockRespDto : stockRespDtos) {
            ItemSyncVO itemSyncVO = itemSyncVOS.stream().filter(inner -> inner.getItemId().equals(stockRespDto.getItemId())).findFirst().orElseThrow(() -> new PrologException("为查询到商品信息"));
            stockRespDto.setItemName(itemSyncVO.getItemName());
            stockRespDto.setItemCode(itemSyncVO.getPieceBarcode());
            stockRespDto.setOwnerName(itemSyncVO.getCargoOwnerName());
        }
        return stockRespDtos;
    }

    @Override
    public List<InboundOrderRespDto> inboundOrderList(InboundOrderReqDto req) {
        if (StrUtil.isNotBlank(req.getItemName()) && StrUtil.isNotBlank(req.getBarCode())) {
            List<ItemBaseInfoVO> itemInfoList = feignGoodsService.getItemByName(req.getItemName());
            List<ItemSyncVO> itemByBarcode = feignGoodsService.getItemByBarcode(req.getBarCode());
            if (CollectionUtils.isEmpty(itemInfoList) && CollectionUtils.isEmpty(itemByBarcode)) {
                req.setItemIds("-1");
            } else if (CollectionUtils.isNotEmpty(itemInfoList) && CollectionUtils.isNotEmpty(itemByBarcode)) {
                List<String> itemIds1 = itemInfoList.stream().map(ItemBaseInfoVO::getItemId).collect(Collectors.toList());
                List<String> itemIds2 = itemByBarcode.stream().map(ItemSyncVO::getItemId).collect(Collectors.toList());
                itemIds1.retainAll(itemIds2);
                req.setItemIds(StrUtil.join(",", itemIds1));
            } else if (CollectionUtils.isNotEmpty(itemInfoList)) {
                List<String> itemIds1 = itemInfoList.stream().map(ItemBaseInfoVO::getItemId).collect(Collectors.toList());
                req.setItemIds(StrUtil.join(",", itemIds1));
            } else if (CollectionUtils.isNotEmpty(itemByBarcode)) {
                List<String> itemIds2 = itemByBarcode.stream().map(ItemSyncVO::getItemId).collect(Collectors.toList());
                req.setItemIds(StrUtil.join(",", itemIds2));
            }
        } else if (StrUtil.isNotBlank(req.getItemName())) {
            List<ItemBaseInfoVO> itemInfoList = feignGoodsService.getItemByName(req.getItemName());
            List<String> itemIds = itemInfoList.stream().map(ItemBaseInfoVO::getItemId).collect(Collectors.toList());
            req.setItemIds(StrUtil.join(",", itemIds));
        } else if (StrUtil.isNotBlank(req.getBarCode())) {
            List<ItemSyncVO> itemByBarcode = feignGoodsService.getItemByBarcode(req.getBarCode());
            List<String> itemIds = itemByBarcode.stream().map(ItemSyncVO::getItemId).collect(Collectors.toList());
            req.setItemIds(StrUtil.join(",", itemIds));
        }
        PageUtils.startPage(req.getPageNum(), req.getPageSize());
        return bizInboundTaskService.inboundOrderList(req);
    }

    @Override
    public List<InboundOrderDetailRespDto> inboundOrderDetail(Integer id) throws Exception {
        List<BizInboundTaskDetail> list = bizInboundTaskDetailService.findInBoundDetailByInboundId(id);
        final List<String> itemIds = list.stream().map(BizInboundTaskDetail::getItemId).collect(Collectors.toList());
        final List<String> lotIds = list.stream().map(BizInboundTaskDetail::getLotId).collect(Collectors.toList());
        final List<ItemSyncVO> itemInfoList = feignGoodsService.queryItemMst(itemIds);
        List<BatchNumberSync> batchNumberSync = inventoryService.getBatchNumberSync(lotIds);
        List<InboundOrderDetailRespDto> result = new ArrayList<>();
        list.forEach(item -> {
            ItemSyncVO itemSyncVO = itemInfoList.stream().filter(inner -> inner.getItemId().equals(item.getItemId())).findFirst().orElseThrow(() -> new PrologException("为查询到商品信息"));
            BatchNumberSync numberSync = batchNumberSync.stream().filter(inner -> inner.getBatchId().equals(item.getLotId())).findFirst().orElseThrow(() -> new PrologException("为查询到批次信息"));
            BigDecimal[] bigDecimals = item.getQty().divideAndRemainder(itemSyncVO.getUomList().get(0).getConversionRate());
            result.add(InboundOrderDetailRespDto.builder()
                    .barCode(itemSyncVO.getPieceBarcode())
                    .id(item.getId())
                    .itemCode(itemSyncVO.getItemCode())
                    .itemName(itemSyncVO.getItemName())
                    .itemQty(bigDecimals[0])
                    .lotNo(numberSync.getBatchNum())
                    .packQty(itemSyncVO.getUomList().get(0).getConversionRate())
                    .qty(item.getQty())
                    .scatteredQty(bigDecimals[1])
                    .build());
        });
        return result;
    }

    @Override
    @Transactional
    public void updatePriority(List<PagePriorityDto> priorityList) {
        for (PagePriorityDto pagePriorityDto : priorityList) {
            final BizOutboundTask bizOutboundTask = bizOutboundTaskMapper.findById(pagePriorityDto.getId(), BizOutboundTask.class);
            AssertUtils.isNotNull(bizOutboundTask, String.format("出库单id%s查询为空", pagePriorityDto.getId()));
            AssertUtils.isNotTrue(bizOutboundTask.getStatus() > 0, String.format("出库单id%s当前状态不支持修改优先级", pagePriorityDto.getId()));
            bizOutboundTask.setPriority(pagePriorityDto.getNewPriority());
            bizOutboundTaskMapper.update(bizOutboundTask);
        }
    }

}
