package com.prolog.eis.strategy.outbound;

import com.prolog.eis.constants.base.ContainerTaskStatusConstants;
import com.prolog.eis.constants.base.OrderStatusConstants;
import com.prolog.eis.dto.strategy.*;
import com.prolog.eis.model.outbound.BizOutboundTask;
import com.prolog.eis.model.outbound.BizOutboundTaskDetail;
import com.prolog.eis.outbound_dispatch.DispatchStrategy;
import com.prolog.eis.service.container.ContainerTaskService;
import com.prolog.eis.service.outbound.BizOutboundTaskDetailService;
import com.prolog.eis.service.outbound.BizOutboundTaskService;
import com.prolog.eis.store_init.StoreInitStrategy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author wk
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class AssignContainerStrategy extends DispatchStrategy {

    private final BizOutboundTaskDetailService bizOutboundTaskDetailService;

    private final BizOutboundTaskService bizOutboundTaskService;

    private final ContainerTaskService containerTaskService;

    @Override
    public void doDispatch(String billType,String warehouseArea, StoreInitStrategy storeInitStrategy) throws Exception {
        InitDto initDto = storeInitStrategy.getInitDto(billType, warehouseArea, this);
        if (Objects.isNull(initDto)) {
            return;
        }
        List<OrderDto> orderList = initDto.getOrderList();
        List<ContainerInfoDto> containerInfoDtoList = initDto.getContainerInfoDtoList();
        List<OrderDto> initOrder =
                orderList.stream().sorted(Comparator.comparing(OrderDto::getPriority).thenComparing(OrderDto::getCreateTime)).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(initOrder)) {
            for (OrderDetailDto detailDto : initOrder.get(0).getOrderDetailDtoList()) {
                ContainerInfoDto containerInfoDto = containerInfoDtoList.stream().filter(x -> x.getContainerNo().equals(detailDto.getContainerNo())).findFirst().orElse(null);
                if (Objects.nonNull(containerInfoDto)){
                    List<ContainerTaskDto> containerTaskDtoList = createContainerDto(initOrder.get(0), detailDto, containerInfoDto);
                    handleOrder(containerTaskDtoList, null, null);
                    containerTaskService.createContainerTaskBatch(containerTaskDtoList);
                }else {
                    log.warn("订单明细行id{}未匹配到容器库存，容器号{}", detailDto.getOrderDetailId(), detailDto.getContainerNo());
                }

            }

        }
    }

    @Override
    public void handleOrder(List<ContainerTaskDto> containerTaskDtoList, String stationId, List<OrderDto> orderDtoList) {
        System.out.println("指定托盘订单处理");
        /*
          指定托盘时，为单调明细处理，然后检查当前订单处理
         */
        ContainerTaskDto containerTaskDto = containerTaskDtoList.get(0);
        List<BizOutboundTaskDetail> bizOutboundTaskDetailList = bizOutboundTaskDetailService.findByOrderId(containerTaskDto.getOrderId());
        BizOutboundTask bizOutboundTask = bizOutboundTaskService.findById(containerTaskDto.getOrderId());
        bizOutboundTaskDetailList.forEach(k -> {
            k.setStatus(OrderStatusConstants.START_STATUS);
            k.setUpdateTime(LocalDateTime.now());
        });
        List<BizOutboundTaskDetail> collect =
                bizOutboundTaskDetailList.stream().filter(bizOutboundTaskDetail -> bizOutboundTaskDetail.getContainerNo().equals(containerTaskDto.getContainerNo())).collect(Collectors.toList());
        bizOutboundTaskDetailService.batchUpdate(collect);
        List<BizOutboundTaskDetail> outboundTaskDetails = bizOutboundTaskDetailList.stream().filter(bizOutboundTaskDetail -> bizOutboundTaskDetail.getStatus() == OrderStatusConstants.INIT_STATUS).collect(Collectors.toList());
        if (outboundTaskDetails.isEmpty()) {
            bizOutboundTask.setStatus(OrderStatusConstants.START_STATUS);
        } else if (bizOutboundTask.getStatus() == OrderStatusConstants.INIT_STATUS) {
            bizOutboundTask.setStatus(OrderStatusConstants.START_STATUS);
        }
        bizOutboundTask.setUpdateTime(LocalDateTime.now());
        bizOutboundTaskService.update(bizOutboundTask);
    }

    @Override
    public void delUseContainer(List<ContainerInfoDto> collect, OrderDto orderDto) {

    }

    private List<ContainerTaskDto> createContainerDto(OrderDto orderDto, OrderDetailDto orderDetailDto, ContainerInfoDto containerInfoDto) {
        List<ContainerTaskDto> containerTaskDtoList = new ArrayList<>();
        ContainerTaskDto containerTaskDto = new ContainerTaskDto();
        containerTaskDto.setContainerNo(containerInfoDto.getContainerNo());
        containerTaskDto.setContainerSubNo(containerInfoDto.getContainerSubNo());
        containerTaskDto.setContainerType(ContainerTaskStatusConstants.ONE_FULL_TRAY_TYPE);
        containerTaskDto.setTaskType(orderDto.getBillType());
        containerTaskDto.setWmsLocationCode(orderDto.getWmsLocationCode());
        containerTaskDto.setBindingNum(containerInfoDto.getQty());
        containerTaskDto.setOrderId(orderDetailDto.getOrderId());
        containerTaskDto.setOrderDetailId(orderDetailDto.getOrderDetailId());
        containerTaskDto.setTargetArea(orderDetailDto.getTargetArea());
        containerTaskDto.setItemId(containerInfoDto.getItemId());
        containerTaskDto.setLotId(containerInfoDto.getLotId());
        containerTaskDto.setPackId(containerInfoDto.getPackId());
        containerTaskDto.setPriority(orderDto.getPriority());
        containerTaskDto.setOwnerId(containerInfoDto.getOwnerId());
        containerTaskDtoList.add(containerTaskDto);
        return containerTaskDtoList;
    }
}
