package com.prolog.eis.strategy.outbound;

import com.prolog.eis.constants.base.OrderStatusConstants;
import com.prolog.eis.dto.strategy.*;
import com.prolog.eis.enums.base.BaseStatusEnum;
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.springframework.stereotype.Component;

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


/**
 * Eis手动组单调度出库策略
 *
 * @author wk
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class EmptyContainerStrategy extends DispatchStrategy {

    private final BizOutboundTaskService bizOutboundTaskService;

    private final BizOutboundTaskDetailService bizOutboundTaskDetailService;

    private final ContainerTaskService containerTaskService;


    @Override
    public void doDispatch(String billType, String warehouseArea, StoreInitStrategy storeInitStrategy) throws Exception {

        System.out.println("Eis空托盘跺出库");
        InitDto initDto = storeInitStrategy.getInitDto(billType, warehouseArea, this);
        if (Objects.isNull(initDto)) {
            return;
        }
        List<ContainerInfoDto> containerInfoDtoList = initDto.getContainerInfoDtoList();
        List<OrderDto> orderList = initDto.getOrderList();
        Map<Integer, String> strategyMap = initDto.getStrategyMap();
        orderList.sort(Comparator.comparing(OrderDto::getEisWaveTime, Comparator.nullsLast(Date::compareTo)).thenComparing(OrderDto::getPriority, Comparator.reverseOrder()).thenComparing(OrderDto::getCreateTime));

        Map<String, BigDecimal> storeMap =
                containerInfoDtoList.stream().collect(Collectors.toMap(ContainerInfoDto::getBusinessProperty, ContainerInfoDto::getQty, (k1, k2) -> k1.add(k2)));
        List<OrderDto> orderDtoList = new ArrayList<>();
        for (OrderDto orderDto : orderList) {
            if (computeStore(orderDto, storeMap)) {
                orderDtoList.add(orderDto);
            }
        }
        if (orderDtoList.isEmpty()) {
            throw new Exception("所有订单库存不足");
        }
        List<ContainerTaskDto> containerTaskDtoList = getGroupList(orderDtoList, containerInfoDtoList, strategyMap, billType);
        handleOrder(containerTaskDtoList, null,null);
        containerTaskService.createContainerTaskBatch(containerTaskDtoList);
    }



    @Override
    public void handleOrder(List<ContainerTaskDto> containerTaskDtoList, String stationId, List<OrderDto> orderDtoList) {
        Map<Integer, List<ContainerTaskDto>> orderMap
                = containerTaskDtoList.stream().collect(Collectors.groupingBy(ContainerTaskDto::getOrderId));
        List<BizOutboundTaskDetail> updateBizOutboundTaskDetailList = new ArrayList<>();
        List<BizOutboundTask> updateBizOutboundTaskList = new ArrayList<>();
        for (Map.Entry<Integer, List<ContainerTaskDto>> orderContainerTask : orderMap.entrySet()) {
            Integer orderId = orderContainerTask.getKey();
            BizOutboundTask bizOutboundTask = bizOutboundTaskService.findById(orderId);
            Map<Integer, List<ContainerTaskDto>> map = orderContainerTask.getValue().stream().collect(Collectors.groupingBy(ContainerTaskDto::getOrderDetailId));
            for (Map.Entry<Integer, List<ContainerTaskDto>> entry : map.entrySet()) {
                BizOutboundTaskDetail bizOutboundTaskDetail = bizOutboundTaskDetailService.findById(entry.getKey());
                bizOutboundTaskDetail.setStatus(BaseStatusEnum.STATUS_STARTED.getCode());
                BigDecimal outQty = entry.getValue().stream().map(ContainerTaskDto::getBindingNum).reduce(BigDecimal.ZERO, BigDecimal::add);
                bizOutboundTaskDetail.setOutQty(outQty);
                bizOutboundTaskDetail.setUpdateTime(LocalDateTime.now());
                updateBizOutboundTaskDetailList.add(bizOutboundTaskDetail);
            }
            bizOutboundTask.setStatus(OrderStatusConstants.START_STATUS);
            bizOutboundTask.setUpdateTime(LocalDateTime.now());
            updateBizOutboundTaskList.add(bizOutboundTask);
        }
        bizOutboundTaskDetailService.batchUpdate(updateBizOutboundTaskDetailList);
        bizOutboundTaskService.batchUpdate(updateBizOutboundTaskList);


    }

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

    }


    private List<ContainerTaskDto> getGroupList(List<OrderDto> orderDtoList, List<ContainerInfoDto> containerInfoDtoList, Map<Integer, String> strategyMap, String billType) throws Exception {
        List<OrderDetailDto> orderDetailDtoList = getAllOrderDetailList(orderDtoList);
        Map<String, List<OrderDetailDto>> detailMap = orderDetailDtoList.stream().collect(Collectors.groupingBy(OrderDetailDto::getBusinessProperty));
        List<ContainerTaskDto> containerTaskDtoList = new ArrayList<>();
        for (String s : detailMap.keySet()) {
            List<OrderDetailDto> detailDtoList = detailMap.get(s);
            getAllTask(orderDtoList, containerInfoDtoList, strategyMap, containerTaskDtoList, detailDtoList);
        }
        return containerTaskDtoList;
    }


    private List<OrderDetailDto> getAllOrderDetailList(List<OrderDto> orderDtoList) {
        List<OrderDetailDto> orderDetailDtoList = new ArrayList<>();
        for (OrderDto orderDto : orderDtoList) {
            orderDetailDtoList.addAll(orderDto.getOrderDetailDtoList());
        }
        return orderDetailDtoList;
    }


}
