package com.clx.performance.extranal.user.impl;

import com.clx.open.sdk.request.dto.BatchOrderStatisticsDTO;
import com.clx.open.sdk.request.dto.BatchOrderStatisticsInfoDTO;
import com.clx.open.sdk.request.dto.OrderStatisticsDTO;
import com.clx.open.sdk.request.dto.OrderStatisticsInfoDTO;
import com.clx.order.feign.OrderFeign;
import com.clx.order.vo.feign.FeignOrderInfoVO;
import com.clx.performance.dao.OrderChildDao;
import com.clx.performance.dao.OrderGoodsDao;
import com.clx.performance.enums.OrderChildEnum;
import com.clx.performance.enums.OrderGoodsStatusEnum;
import com.clx.performance.extranal.user.OrderService;
import com.clx.performance.model.OrderChild;
import com.clx.performance.model.OrderGoods;
import com.clx.performance.service.PerformanceProgressService;
import com.clx.performance.utils.spring.ApplicationContextUtils;
import com.msl.common.base.Optional;
import com.msl.common.result.Result;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.*;

@Service
@Slf4j
@AllArgsConstructor
public class OrderServiceImpl implements OrderService {

    private final OrderFeign orderFeign;
    private final OrderGoodsDao orderGoodsDao;
    private final OrderChildDao orderChildDao;

    @Override
    public Optional<FeignOrderInfoVO> getOrderInfo(String orderNo) {
        return Optional.ofNullable(orderFeign.getOrderInfo(orderNo))
                .filter(Result::succeed)
                .map(Result::getData);
    }

    @Override
    public Optional<List<String>> getMonthSameLineOrderList(String orderNo) {
        return Optional.ofNullable(orderFeign.getMonthSameLineOrderList(orderNo))
                .filter(Result::succeed)
                .map(Result::getData);
    }

    @Override
    public Optional<Map<String,FeignOrderInfoVO>> queryListOrderByOrderNoList(List<String> orderNoList) {
        return Optional.ofNullable(orderFeign.queryListOrderByOrderNoList(orderNoList))
                .filter(Result::succeed)
                .map(Result::getData);
    }

    @Override
    public BatchOrderStatisticsInfoDTO queryTaskStatisticsInfo(List<String> orderNoList) {
        BatchOrderStatisticsInfoDTO returnResult = new BatchOrderStatisticsInfoDTO();
        //构建结果集
        Map<String, OrderStatisticsInfoDTO> result = new HashMap<>();
        orderNoList.forEach(item->{
            OrderStatisticsInfoDTO dto = new OrderStatisticsInfoDTO();
            dto.setOrderNo(item);
            dto.setPendingTruckNum(0);
            dto.setOrderedTruckNum(0);
            dto.setNotLoadTruckNum(0);
            dto.setArriveSendTruckNum(0);
            dto.setArriveReceiveTruckNum(0);
            dto.setLoadTruckNum(0);
            dto.setUnLoadTruckNum(0);
            dto.setLoadWeight(BigDecimal.ZERO);
            dto.setUnLoadWeight(BigDecimal.ZERO);
            result.put(item,dto);
        });

        List<OrderGoods> orderGoods = orderGoodsDao.listInField(OrderGoods::getOrderNo, orderNoList);

        if(CollectionUtils.isEmpty(orderGoods)){
            returnResult.setList(new ArrayList<>(result.values()));
            return returnResult;
        }
        //计算挂单车数
        for (OrderGoods orderGood : orderGoods) {
            if(Objects.equals(orderGood.getOrderGoodsStatus(), OrderGoodsStatusEnum.Status.CANCEL.getCode())){
                continue;
            }
            OrderStatisticsInfoDTO dto = result.get(orderGood.getOrderNo());
            dto.setPendingTruckNum(dto.getPendingTruckNum() + orderGood.getNeedTruckNum());
            result.put(orderGood.getOrderNo(),dto);
        }
        //计算运单相关统计数据
        List<OrderChild> childList = orderChildDao.listInField(OrderChild::getOrderNo, orderNoList);
        if(CollectionUtils.isEmpty(childList)){
            returnResult.setList(new ArrayList<>(result.values()));
            return returnResult;
        }

        for (OrderChild child : childList) {
            OrderStatisticsInfoDTO dto = result.get(child.getOrderNo());
            //取消的排除
            if(child.getStatus() > OrderChildEnum.Status.COMPLETE.getCode()){
                continue;
            }
            //未取消的运单 接单数
            dto.setOrderedTruckNum(dto.getOrderedTruckNum() + 1);

            if(child.getStatus() >=OrderChildEnum.Status.CREATED.getCode()  &&
                    child.getStatus() < OrderChildEnum.Status.LOAD.getCode() ){
                dto.setNotLoadTruckNum(dto.getNotLoadTruckNum() + 1);
            }
            //到达货源地
            if(Objects.equals(child.getStatus(),OrderChildEnum.Status.ARRIVE_SEND.getCode())){
                dto.setArriveSendTruckNum(dto.getArriveSendTruckNum() + 1);
            }
            //到达卸车地
            if(Objects.equals(child.getStatus(),OrderChildEnum.Status.ARRIVE_RECEIVE.getCode())){
                dto.setArriveReceiveTruckNum(dto.getArriveReceiveTruckNum() + 1);
            }

            //已装车
            if(child.getStatus() >= OrderChildEnum.Status.LOAD.getCode()){
                dto.setLoadTruckNum(dto.getLoadTruckNum() + 1);
                dto.setLoadWeight(dto.getLoadWeight().add(child.getLoadNet()));
            }
            //已卸车
            if(child.getStatus() >= OrderChildEnum.Status.UNLOAD.getCode()){
                dto.setUnLoadTruckNum(dto.getUnLoadTruckNum() + 1);
                dto.setUnLoadWeight(dto.getUnLoadWeight().add(child.getUnloadNet()));
            }
            result.put(child.getOrderNo(),dto);
        }
        returnResult.setList(new ArrayList<>(result.values()));
        return returnResult;
    }

    @Override
    public BatchOrderStatisticsDTO queryOrderStatistics(List<String> orderNoList) {

        BatchOrderStatisticsDTO returnResult = new BatchOrderStatisticsDTO();
        //构建结果集
        Map<String, OrderStatisticsDTO> result = new HashMap<>();
        orderNoList.forEach(item->{
            OrderStatisticsDTO dto = new OrderStatisticsDTO();
            dto.setOrderNo(item);
            dto.setPendingWeight(BigDecimal.ZERO);
            result.put(item,dto);
        });

        List<OrderGoods> orderGoods = orderGoodsDao.listInField(OrderGoods::getOrderNo, orderNoList);
        if(CollectionUtils.isEmpty(orderGoods)){
            returnResult.setList(new ArrayList<>(result.values()));
            return returnResult;
        }

        //计算已挂单吨数
        for (OrderGoods orderGood : orderGoods) {
            if(Objects.equals(orderGood.getOrderGoodsStatus(), OrderGoodsStatusEnum.Status.CANCEL.getCode())){
                continue;
            }
            OrderStatisticsDTO dto = result.get(orderGood.getOrderNo());
            BigDecimal pendingWeight = ApplicationContextUtils.getBean(PerformanceProgressService.class).calcPendingWeight(
                    orderGood);
            dto.setPendingWeight(dto.getPendingWeight().add(pendingWeight));
            result.put(orderGood.getOrderNo(),dto);
        }
        returnResult.setList(new ArrayList<>(result.values()));
        return returnResult;
    }
}
