package com.sckw.usual.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sckw.usual.entity.*;
import com.sckw.usual.entity.req.waybill.SendCarDto;
import com.sckw.usual.entity.req.waybill.SendCarEntrustDto;
import com.sckw.usual.entity.req.waybill.WaybillFinishReq;
import com.sckw.usual.entity.req.waybill.WaybillPageListReq;
import com.sckw.usual.entity.res.waybill.WaybillPageListRes;
import com.sckw.usual.enums.*;
import com.sckw.usual.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.sckw.core.model.constant.Global;
import com.sckw.core.utils.*;
import com.sckw.core.model.enums.*;
import com.sckw.core.model.page.PageRes;
import com.sckw.core.web.response.HttpResult;
import java.math.BigDecimal;
import java.sql.Array;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @desc:
 * @author: lt
 * @date: 2024/4/9 14:41
 */
@Service
public class WaybillOrderService {

    @Autowired
    OrderGeneralTransportMapper logisticsOrderDao;

    @Autowired
    KwOrderUsualLandTransportAddressMapper kwOrderUsualLandTransportAddressMapper;

    @Autowired
    OrderGeneralTransportGoodsMapper orderGeneralTransportGoodsMapper;

    @Autowired
    KwOrderUsualLandTransportCirculateMapper kwOrderUsualLandTransportCirculateMapper;

    @Autowired
    KwOrderUsualLandTransportTrackMapper kwOrderUsualLandTransportTrackMapper;

    @Autowired
    KwWaybillOrderMapper kwWaybillOrderMapper;

    @Autowired
    KwWaybillOrderAddressMapper kwWaybillOrderAddressMapper;

    @Autowired
    KwWaybillOrderTrackMapper kwWaybillOrderTrackMapper;

    @Autowired
    OrderDictService orderDictService;

    @Autowired
    KwOrderCarWaybillDisAddressMapper kwOrderCarWaybillDisAddressMapper;

    @Autowired
    KwOrderUsualLandTransportAmountMapper kwOrderUsualLandTransportAmountMapper;

    @Autowired
    kwWaybillOrderFinishMapper kwWaybillOrderFinishMapper;


    /**
     * @return
     * @Description: 运单分页列表
     * @Author: Lt
     * @Date: 2024/4/29 14:16
     */
    public PageRes<WaybillPageListRes> waybillPageList(WaybillPageListReq waybillPageListReq)
    {
        PageHelper.startPage(waybillPageListReq.getPage(), waybillPageListReq.getPageSize());
        List<WaybillPageListRes> kwBusinessPaths = kwWaybillOrderMapper.selectPageList(waybillPageListReq);

        Map<String, Map<String, String>> dict = orderDictService.queryDictByType(new ArrayList<>(Arrays.asList(
                OrderDictTypeEnum.ORDER_SOURCE.getType(),
                OrderDictTypeEnum.OW_SYSTEM.getType(),
                OrderDictTypeEnum.GOODS_UNIT.getType()
        )));
        Map<String, String> orderSourceMap, owSystemMap, goodsUnitMap;
        if (CollectionUtils.isNotEmpty(dict)) {
            orderSourceMap = CollectionUtils.isNotEmpty(dict.get(OrderDictTypeEnum.ORDER_SOURCE.getType())) ? dict.get(OrderDictTypeEnum.ORDER_SOURCE.getType()) : new HashMap<>(16);
            owSystemMap = CollectionUtils.isNotEmpty(dict.get(OrderDictTypeEnum.OW_SYSTEM.getType())) ? dict.get(OrderDictTypeEnum.OW_SYSTEM.getType()) : new HashMap<>(16);
            goodsUnitMap = CollectionUtils.isNotEmpty(dict.get(OrderDictTypeEnum.GOODS_UNIT.getType())) ? dict.get(OrderDictTypeEnum.GOODS_UNIT.getType()) : new HashMap<>(16);
        } else {
            orderSourceMap = new HashMap<>(16);
            owSystemMap = new HashMap<>(16);
            goodsUnitMap = new HashMap<>(16);
        }

        // 获取所有的 waybillIds
        List<Long> waybillIds = kwBusinessPaths.stream()
                .filter(e -> e.getTType().equals(WayBillTypeEnum.TWO.getCode())) // 仅获取轿运的运单ID
                .map(WaybillPageListRes::getWaybillId)
                .map(Long::valueOf)
                .collect(Collectors.toList());
        // 如果存在轿运的运单ID，查询对应的 goods_name
        Map<Long, String> waybillIdToGoodsNamesMap = new HashMap<>();
        if (!waybillIds.isEmpty()) {
            List<WaybillGoodsDto> waybillGoodsList = kwWaybillOrderMapper.findByWaybillIds(waybillIds);
            waybillIdToGoodsNamesMap = waybillGoodsList.stream()
                    .collect(Collectors.groupingBy(
                            WaybillGoodsDto::getWaybillId,
                            Collectors.mapping(WaybillGoodsDto::getGoodsName, Collectors.toSet()) // 先转换为 Set
                    ))
                    .entrySet().stream()
                    .collect(Collectors.toMap(
                            Map.Entry::getKey,
                            e -> String.join(",", new ArrayList<>(e.getValue())) // 再转换回 List 并用逗号连接
                    ));
        }

        final Map<Long, String> finalWaybillIdToGoodsNamesMap = waybillIdToGoodsNamesMap;
        kwBusinessPaths.forEach(e -> {
            e.setOrderSourceStr(orderSourceMap.get(e.getOrderSource().toString()));
            e.setTTypeStr(WayBillTypeEnum.getNameByCode(e.getTType()));
            e.setOwSystem(owSystemMap.get(e.getOwSystem()));
            e.setStatusStr(WayBillStatusEnum.getNameByCode(e.getStatus()));

            // 初始化列表
            List<String> loadAddress = new ArrayList<>();
            List<String> unLoadAddress = new ArrayList<>();

            //如果是陆运
            if (e.getTType().equals(WayBillTypeEnum.ONE.getCode())){
                List<KwOrderUsualLandTransportAddress> byAddress = kwOrderUsualLandTransportAddressMapper.findByAddressByOrderId(Long.valueOf(e.getOrderId()));
                // 遍历查询结果，根据type进行分类
                for (KwOrderUsualLandTransportAddress address : byAddress) {
                    if (address.getAddressType() == 1) {
                        // 如果type为1，则添加到loadAddress列表
                        loadAddress.add(address.getName());
                    } else if (address.getAddressType() == 2) {
                        // 如果type为2，则添加到unLoadAddress列表
                        unLoadAddress.add(address.getName());
                    }
                    // 注意：如果还有其他type，可以继续添加else if分支处理
                }
                KwOrderUsualLandTransportGoods byGoods = orderGeneralTransportGoodsMapper.findByGoods(Long.valueOf(e.getOrderId()));
                e.setGoodsName(byGoods.getGoodsName());
                e.setUnitStr(goodsUnitMap.get(byGoods.getGoodsUnit().toString()));
            }
            //如果是轿运88
            if (e.getTType().equals(WayBillTypeEnum.TWO.getCode())){
                List<KwOrderCarWaybillDisAddress> byAddress = kwOrderCarWaybillDisAddressMapper.findByAddressByOrderId(Long.valueOf(e.getWaybillId()));

                //e.setGoodsName();
                // 遍历查询结果，根据type进行分类
                for (KwOrderCarWaybillDisAddress address : byAddress) {
                    if (address.getAddressType() == 1) {
                        // 如果type为1，则添加到loadAddress列表
                        loadAddress.add(address.getName());
                    } else if (address.getAddressType() == 2) {
                        // 如果type为2，则添加到unLoadAddress列表
                        unLoadAddress.add(address.getName());
                    }
                    // 注意：如果还有其他type，可以继续添加else if分支处理
                }
                e.setGoodsName(finalWaybillIdToGoodsNamesMap.get(Long.valueOf(e.getWaybillId())));
            }


            // 假设'e'是WaybillPageListRes类型的实例，现在将处理好的地址列表设置进去
            e.setLoadAddress(loadAddress);
            e.setUnLoadAddress(unLoadAddress);
        });

        Map<Integer, List<Integer>> typeIdToWaybillIds = new HashMap<>();
        kwBusinessPaths.forEach(res -> typeIdToWaybillIds.computeIfAbsent(res.getTType(), k -> new ArrayList<>()).add(res.getTType()));


        return new PageRes<>(new PageInfo<>(kwBusinessPaths));
    }

    public HttpResult sendCarV2(List<SendCarDto> params)
    {
        /*1、校验*/
        HttpResult result = checkWaybillOrderV1(params);

        /*2、新增运单相关信息*/
        List<SendCarEntrustDto> sendCarEntrustAll = ranksSave2(params);

        /*3、更新承运订单委派信息*/
        List<Long> lOrderIds = editLogisticsOrder(sendCarEntrustAll);
        /*4、更新承运订单状态（包括上级承运订单）*/
        editLogisticsOrderStatus(lOrderIds);
        return HttpResult.ok();
    }

    /**
     * @param lOrderIds 物流订单集
     * @desc 更新承运订单状态信息（包括分包上级物流订单）
     * @author zk
     * @date 2024/3/5
     **/
    public void editLogisticsOrderStatus(List<Long> lOrderIds) {
        for (Long lOrderId : lOrderIds) {
            //物流订单信息
            KwOrder logisticsOrder = logisticsOrderDao.selectById(lOrderId);
            //当前承运订单所属分包层级
            String pids = logisticsOrder.getPids();
            if (StringUtils.isNotBlank(pids)) {
                String[] idArray = pids.split(Global.COMMA);
                for (String id : idArray) {
                    KwOrder order = logisticsOrderDao.selectById(id);
                    //承运订单-待派车
                    if (order.getStatus().equals(OrderUsualStatusEnum.WAIT_TRANSPORT.getCode())) {
                        //更新当前承运订单状态(待派车->运输中)
                        order.setStatus(OrderUsualStatusEnum.IN_TRANSIT.getCode());
                        logisticsOrderDao.updateById(order);

                        //承运订单状态记录
                        KwOrderUsualLandTransportTrack orderTrack = new KwOrderUsualLandTransportTrack();
                        orderTrack.setOrderId(order.getId());
                        orderTrack.setStatus(order.getStatus());
                        orderTrack.setRemark(OrderUsualStatusEnum.getNameByCode(order.getStatus()));
                        kwOrderUsualLandTransportTrackMapper.insert(orderTrack);
                    }
                }
            }
        }
    }

    /**
     * @param sendCarEntrusts 委派参数
     * @desc 更新承运订单委派信息
     * @author zk
     * @date 2024/3/5
     **/
    public List<Long> editLogisticsOrder(List<SendCarEntrustDto> sendCarEntrusts) {
        //物流订单ID
        List<Long> lOrderIds = new ArrayList<>();
        //数据组装-数据统计
        BigDecimal totalLoadNum = BigDecimal.ZERO;
        BigDecimal totalUnLoadNum = BigDecimal.ZERO;
        Long orderId = null;
        for (SendCarEntrustDto sendCarEntrust : sendCarEntrusts) {
            if (sendCarEntrust.getAddressType() == AddressTypeEnum.LOAD_ADDRESS.getCode())  {
                orderId = sendCarEntrust.getOrderId();
                totalLoadNum = totalLoadNum.add(BigDecimal.valueOf(sendCarEntrust.getEntrustAmount()));
            } else if (sendCarEntrust.getAddressType() == AddressTypeEnum.UNLOAD_ADDRESS.getCode()) {
                totalUnLoadNum = totalUnLoadNum.add(BigDecimal.valueOf(sendCarEntrust.getEntrustAmount()));
            }
        }

        KwOrder logisticsOrder = logisticsOrderDao.selectById(orderId);

        if (totalLoadNum.compareTo(logisticsOrder.getRemainAllocation()) > 0) {
            throw new RuntimeException("剩余待分配量不足");
        }

        //直接扣待分配
        //剩余待分配量 = 货物数量 - 已派车的装载量
        //剩余待分配量
        BigDecimal subtract = logisticsOrder.getRemainAllocation().subtract(totalLoadNum);
        //已派车量 totalLoadNum
        KwOrder kwOrder = new KwOrder();

        kwOrder.setId(orderId).setLoadAmount(subtract)
                .setUnloadAmount(totalUnLoadNum)
                .setStatus(OrderUsualStatusEnum.IN_TRANSIT.getCode())
                .setRemainAllocation(subtract);
        logisticsOrderDao.updateById(kwOrder);

        return lOrderIds.stream().distinct().toList();
    }

    @Transactional(rollbackFor = Exception.class)
    public List<SendCarEntrustDto> ranksSave2(List<SendCarDto> params) {
        //车辆司机信息
        //物流订单对应地址信息(所有)
        List<SendCarEntrustDto> sendCarEntrustAll = new ArrayList<>();

        ArrayList<KwWaybillOrderAddress> wayBillAddressList = new ArrayList<>();
        for (SendCarDto param : params) {
                //新增运单信息
            KwWaybillOrder waybillOrder = sendCarDriver(param);
            //运输委托信息
            List<SendCarEntrustDto> entrusts = param.getEntrusts();
            //物流订单对应地址信息
            Map<Long, List<SendCarEntrustDto>> sendCarEntrusts = new HashMap<>(Global.NUMERICAL_SIXTEEN);
            //数据组装-物流订单归类（合并派车）
            for (SendCarEntrustDto sendCarEntrust : entrusts) {
                //物流订单ID
                Long lOrderId = sendCarEntrust.getOrderId();
                /* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓添加运单地址信息↓↓↓↓↓↓↓↓↓↓↓↓ */
                KwWaybillOrderAddress kwWaybillOrderAddress = saveWaybillAddress(lOrderId, sendCarEntrust);
                wayBillAddressList.add(kwWaybillOrderAddress);
                /* ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ */
                //委派信息
                List<SendCarEntrustDto> entrustDtos = new ArrayList<>() {{
                    add(sendCarEntrust);
                }};
                if (sendCarEntrusts.get(lOrderId) == null) {
                    sendCarEntrusts.put(lOrderId, entrustDtos);
                } else {
                    entrustDtos.addAll(sendCarEntrusts.get(lOrderId));
                    sendCarEntrusts.put(lOrderId, entrustDtos);
                }
                sendCarEntrustAll.add(sendCarEntrust);
            }

            /*车辆运单状态记录*/
            this.setWaybillOrderTrack(waybillOrder.getId(),  waybillOrder.getUpdateTime(), waybillOrder.getStatus(), null);
        }


        kwWaybillOrderAddressMapper.insertBatch(wayBillAddressList);
        return sendCarEntrustAll;
    }

    public KwWaybillOrderAddress saveWaybillAddress(Long lOrderId,SendCarEntrustDto sendCarEntrust)
    {
        KwWaybillOrderAddress kwWaybillOrderAddress = new KwWaybillOrderAddress();
        kwWaybillOrderAddress.setId(new IdWorker(1L).nextId());
        kwWaybillOrderAddress.setOrderId(lOrderId);
        kwWaybillOrderAddress.setAddressType(sendCarEntrust.getAddressType());
        kwWaybillOrderAddress.setLAddressId(sendCarEntrust.getAddressId());
        kwWaybillOrderAddress.setUnit(sendCarEntrust.getUnit());
        kwWaybillOrderAddress.setContacts(sendCarEntrust.getContacts());
        kwWaybillOrderAddress.setEntrustAmount(sendCarEntrust.getEntrustAmount());
        kwWaybillOrderAddress.setPlanTime(sendCarEntrust.getPlanTime());
        kwWaybillOrderAddress.setSort(sendCarEntrust.getSort());
        kwWaybillOrderAddress.setName(sendCarEntrust.getName());
        kwWaybillOrderAddress.setStatus(WayBillStatusEnum.ONE.getCode());
        return kwWaybillOrderAddress;
    }

    public KwWaybillOrder sendCarDriver(SendCarDto sendCar) {
        //车辆运单编号存储
        //String wOrderNo = getRedisGenerateWaybillOrderNo(RedisOrderGenerateEnum.WAYBILL_ORDER, OrderRuleEnum.WAYBILL_ORDER, logisticsOrder.getLOrderNo());
        //车辆信息
        //运单信息
        KwWaybillOrder waybillOrder = new KwWaybillOrder();
        waybillOrder.setTOrderNo("W" + System.currentTimeMillis());
        waybillOrder.setTruckId(sendCar.getTruckId());
        waybillOrder.setTruckNo(sendCar.getTruckNo());
        waybillOrder.setOrderId(sendCar.getOrderId());
        waybillOrder.setDriverId(sendCar.getDriverId());
        waybillOrder.setDriverName(sendCar.getDriverName());
        waybillOrder.setDriverPhone(sendCar.getDriverPhone());
        waybillOrder.setDriverIdcard(sendCar.getDriverIdcard());
        waybillOrder.setStatus(CarWaybillEnum.ONE.getCode());
        waybillOrder.setEntrustAmount(BigDecimal.valueOf(sendCar.getAmount()));
        waybillOrder.setTType(Global.NUMERICAL_ONE);
        waybillOrder.setCreateBy("admin");
        kwWaybillOrderMapper.insert(waybillOrder);

        return waybillOrder;
    }

    public HttpResult checkWaybillOrderV1(List<SendCarDto> params) {
        //物流订单ID
        List<Long> lOrderIds = new ArrayList<>();
        //物流订单装卸货地址委派量统计
        Map<Long, BigDecimal> truckTotalEntrustAmount = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        for (SendCarDto param : params) {
            //趟次单(循环单默认趟次为1)
            //int count = param.getType() == Global.NUMERICAL_ONE ? param.getCount() : Global.NUMERICAL_ONE;
            //运输委托信息
            List<SendCarEntrustDto> entrusts = param.getEntrusts();
            /*数据组装*/
            for (SendCarEntrustDto sendCarEntrust : entrusts) {
                lOrderIds.add(sendCarEntrust.getOrderId());
                //承运订单该车辆计划运输总量：核定载量 * 趟次
                BigDecimal entrustAmount = BigDecimal.valueOf(sendCarEntrust.getEntrustAmount());
                BigDecimal totalEntrustAmount = truckTotalEntrustAmount.get(sendCarEntrust.getAddressId()) != null
                        ? truckTotalEntrustAmount.get(sendCarEntrust.getAddressId()) : BigDecimal.valueOf(Global.NUMERICAL_TWO);
                truckTotalEntrustAmount.put(sendCarEntrust.getAddressId(), totalEntrustAmount.add(entrustAmount));
            }
        }
        List<Long> lOrderIdsList = lOrderIds.stream().distinct().toList();

        /*校验物流运单是否可以派车*/
        for (Long orderId : lOrderIdsList) {
            KwOrder logisticsOrder = logisticsOrderDao.selectById(orderId);
            if (logisticsOrder == null) {
                return HttpResult.error("订单" + orderId + "已不存在！");
            }
            if (logisticsOrder.getRemainAllocation().compareTo(BigDecimal.ZERO) < Global.NUMERICAL_ZERO)  {
                return HttpResult.error("订单" + orderId + "剩余可运量不足！");
            }

            //状态校验   待派车-运输中
            if (!logisticsOrder.getStatus().equals(OrderUsualStatusEnum.WAIT_TRANSPORT.getCode())
                    && !logisticsOrder.getStatus().equals(OrderUsualStatusEnum.IN_TRANSIT.getCode())) {
                return HttpResult.error("订单" + logisticsOrder.getOrderNo() + OrderUsualStatusEnum.getNameByCode(logisticsOrder.getStatus()) + "不能派车！");
            }

            //剩余可运量校验
            BigDecimal entrustAmount = logisticsOrder.getEntrustAmount() == null ? new BigDecimal(Global.AMOUNT) : logisticsOrder.getEntrustAmount();
            BigDecimal subcontractAmount = logisticsOrder.getSubcontractAmount() == null ? new BigDecimal(Global.AMOUNT) : logisticsOrder.getSubcontractAmount();
            //历史下游司机委派量 + 分包量
            BigDecimal entrustAmountTotal = entrustAmount.add(subcontractAmount);
            if (entrustAmountTotal.compareTo(logisticsOrder.getAmount()) > 0) {
                return HttpResult.error("订单" + logisticsOrder.getOrderNo() + "剩余可运量已不能派车！");
            }

            /*校验是车辆委托量否超过物流订单剩余量-趟次*/
            //物流订单地址委托量信息-装货信息
            KwOrderUsualLandTransportAddress queryAmount = new KwOrderUsualLandTransportAddress();
            queryAmount.setOrderId(orderId);
            queryAmount.setAddressType(AddressTypeEnum.LOAD_ADDRESS.getCode());
            List<KwOrderUsualLandTransportAmount> logisticsOrderAmounts = kwOrderUsualLandTransportAmountMapper.findByAddress(queryAmount);
            for (KwOrderUsualLandTransportAmount orderAmount : logisticsOrderAmounts) {
                BigDecimal truckEntrustAmount = truckTotalEntrustAmount.get(orderAmount.getAddressId());
                if (Objects.isNull(truckEntrustAmount)) {
                    continue;
                }
                //剩余可运量 = 当前上游委派量 - 历史下游司机委派量 - 分包量
                BigDecimal surplusAmount = orderAmount.getAmount().subtract(orderAmount.getEntrustAmount()).subtract(orderAmount.getSubcontractAmount());
                if (surplusAmount.doubleValue() < truckEntrustAmount.doubleValue()) {
                    KwOrderUsualLandTransportAddress address = kwOrderUsualLandTransportAddressMapper.selectById(orderAmount.getAddressId());
                    return HttpResult.error(address.getName() + "剩余量为" + surplusAmount.doubleValue()
                            + "，当前累计派车量为" + truckEntrustAmount.doubleValue() +"，可运量小于累计派车量则不能派车！");
                }
            }
        }
        return HttpResult.ok(truckTotalEntrustAmount);
    }



    @Transactional(rollbackFor = Exception.class)
    public HttpResult sendCar(List<SendCarDto> params) {
        /**校验**/
        //承运单信息
        KwOrder logisticsOrder = logisticsOrderDao.selectById(params.get(0).getOrderId());
        HttpResult result = checkWaybillOrder(params, logisticsOrder);
        if (result.getCode() != 200) {
            return result;
        }
        //下游司机委派量累加（趟次）
        BigDecimal ranksAmount = (BigDecimal) result.getData();

        /**数据处理**/
        result = setWaybillOrder(params, logisticsOrder);
        if (result.getCode() != 200) {
            return result;
        }
        //Mongodb数据存储model
        //List<SckwWaybillOrder> sckwWaybillOrders = (List<SckwWaybillOrder>) result.getData();

        /**变更承运单状态（累计派车量等于剩余可运量）/已委托量entrust_amount**/
        //更新当前承运订单委派量entrustAmount
        BigDecimal entrustAmount = logisticsOrder.getEntrustAmount() == null ? new BigDecimal(Global.COMMA) : logisticsOrder.getEntrustAmount();
        logisticsOrder.setEntrustAmount(entrustAmount.add(ranksAmount));
        logisticsOrderDao.updateById(logisticsOrder);
        //派车更新承运订单信息
        setLogisticsBySendCar(logisticsOrder.getId());

        /**Mongodb数据存储**/
        //1车辆订单
        //for (SckwWaybillOrder waybillOrder : sckwWaybillOrders) {
        //    editSckwWaybillOrder(waybillOrder, null, Global.NUMERICAL_ONE);
        //}
        //
        ////2承运订单
        //SckwLogisticsOrder lOrder = new SckwLogisticsOrder();
        //editSckwLogisticsOrder(lOrder, logisticsOrder);

        /**发送消息**/
        return HttpResult.ok();
    }

    public void setLogisticsBySendCar(Long lOrderId) {
        /**
         状态判断是否是分包承运单（不考虑该承运单下级分包）
         存在：更新当前承运订单状态及委派量entrustAmount，并且校验承运订单所有父级状态是否需要修改（是修改状态，否则不修改）
         不存在：更新当前承运订单状态及委派量entrustAmount
         **/
        //承运单信息
        KwOrder logisticsOrder = logisticsOrderDao.selectById(lOrderId);

        //当前承运订单所属分包层级
        //int level = checkLogisticsLevel(logisticsOrder);
        String pids = logisticsOrder.getPids();
        if (StringUtils.isNotBlank(pids)) {
            String[] idArray = pids.split(Global.COMMA);
            for (String id : idArray) {
                KwOrder order = logisticsOrderDao.selectById(id);
                System.out.println(order);
                //承运订单-待派车
                if (Objects.equals(order.getStatus(), OrderUsualStatusEnum.IN_TRANSIT.getCode())) {
                    //更新当前承运订单状态
                    /**承运订单:待派车->运输中**/
                    order.setStatus(OrderUsualStatusEnum.IN_TRANSIT.getCode());
                    logisticsOrderDao.updateById(order);

                    /**承运订单状态记录**/
                    KwOrderUsualLandTransportTrack orderTrack = new KwOrderUsualLandTransportTrack();
                    orderTrack.setOrderId(order.getId());
                    orderTrack.setStatus(order.getStatus());
                    //orderTrack.setRemark(LogisticsOrderEnum.getName(order.getStatus()));
                    kwOrderUsualLandTransportTrackMapper.insert(orderTrack);

                    /**Mongodb数据更新**/
                    //2承运订单
                    //SckwLogisticsOrder lOrder = new SckwLogisticsOrder();
                    //editSckwLogisticsOrder(lOrder, order);
                }
            }
        }
    }

    public HttpResult checkWaybillOrder(List<SendCarDto> params, KwOrder logisticsOrder) {
        /**校验物流运单是否可以派车**/
        if (logisticsOrder == null) {
            return HttpResult.error("订单已不存在！");
        }

        //状态校验
        if (!Objects.equals(logisticsOrder.getStatus(), OrderUsualStatusEnum.WAIT_TRANSPORT.getCode())
                && !Objects.equals(logisticsOrder.getStatus(), OrderUsualStatusEnum.IN_TRANSIT.getCode())) {

        }

        //amount > 0的时候才可以派车
        //if (logisticsOrder.getAmount().compareTo(BigDecimal.ZERO) < Global.NUMERICAL_ONE) {
        //    return HttpResult.error("订单" + OrderStatusEnum.getNameByCode(logisticsOrder.getStatus()) + "不能派车！");
        //}

        //剩余可运量校验
        BigDecimal entrustAmount = logisticsOrder.getEntrustAmount() == null ? new BigDecimal(Global.AMOUNT) : logisticsOrder.getEntrustAmount();
        BigDecimal subcontractAmount = logisticsOrder.getSubcontractAmount() == null ? new BigDecimal(Global.AMOUNT) : logisticsOrder.getSubcontractAmount();
        //历史下游司机委派量 + 分包量
        BigDecimal entrustAmountTotal = entrustAmount.add(subcontractAmount);
        if (entrustAmountTotal.compareTo(logisticsOrder.getAmount()) > 0) {
            return HttpResult.error("剩余可运量已不能派车！");
        }

        /**校验是车辆委托量否超过物流订单剩余量**/
        //下游司机委派量累加（趟次）
        BigDecimal ranksAmount = new BigDecimal(Global.AMOUNT);
        for (SendCarDto sendCarDto : params) {
            if (sendCarDto.getType() == Global.NUMERICAL_ONE) {
                //趟次派车趟次数量必填
                if (sendCarDto.getAmount() == null || sendCarDto.getAmount() <= 0) {
                    return HttpResult.error(sendCarDto.getTruckNo() + "履约量必须等于或大于0！");
                }
                //承运订单该车辆计划运输总量：核定载量 * 趟次
                Double truckEntrustAmount = sendCarDto.getAmount();
                ranksAmount = ranksAmount.add(new BigDecimal(String.valueOf(truckEntrustAmount)));

                //当前下游司机委派量 + 历史下游司机委派量 + 分包量
                BigDecimal actualAmount = ranksAmount.add(entrustAmountTotal);
                if (actualAmount.doubleValue() > logisticsOrder.getAmount().doubleValue()) {
                    return HttpResult.error("累计装卸量已大于分配量！");
                }
            }
        }
        return HttpResult.ok(ranksAmount);
    }

    public KwOrderUsualLandTransportCirculate circulateSave(KwWaybillOrder waybillOrder) {
        //循环派车信息
        KwOrderUsualLandTransportCirculate circulate = kwOrderUsualLandTransportCirculateMapper.findCirculate(waybillOrder.getOrderId(),
                waybillOrder.getTruckId(), waybillOrder.getDriverId());
        if (circulate == null) {
            circulate = new KwOrderUsualLandTransportCirculate();
            BeanUtils.copyProperties(waybillOrder, circulate);
            circulate.setOrderId(null);
            circulate.setStatus(0);
            int count = kwOrderUsualLandTransportCirculateMapper.insert(circulate);
            return count > 0 ? circulate : null;
        } else {
            //有效循环单不做新增处理、已撤回/拒绝出车更新循环单信息
            if (circulate.getStatus() == Global.NO) {
                return null;
            }

            //更新原循环单ID
            Long newId = new IdWorker(Global.NUMERICAL_ONE).nextId();
            kwOrderUsualLandTransportCirculateMapper.updateIdByKey(newId, null, circulate.getId(), null, new Date());

            BeanUtils.copyProperties(waybillOrder, circulate);
            circulate.setId(newId);
            circulate.setTOrderId(null);
            circulate.setStatus(0);
            int count = kwOrderUsualLandTransportCirculateMapper.updateById(circulate);
            return count > 0 ? circulate : null;
        }
    }

    public HttpResult setWaybillOrder(List<SendCarDto> params, KwOrder logisticsOrder) {
        /**获取基础信息**/
        //装货地址
        List<KwWaybillOrderAddress> loadAddress = this.getAddress(logisticsOrder.getId(), Global.NUMERICAL_ONE, Global.NUMERICAL_ONE);
        //卸货地址
        List<KwWaybillOrderAddress> unloadAddress = this.getAddress(logisticsOrder.getId(), Global.NUMERICAL_TWO, Global.NUMERICAL_ONE);
        //托运企业
       // KwtLogisticsOrderUnit checkEnt = logisticsOrderUnitDao.findByUnit(logisticsOrder.getId(), Global.NUMERICAL_ONE);
        //承运企业
       // KwtLogisticsOrderUnit carrierEnt = logisticsOrderUnitDao.findByUnit(logisticsOrder.getId(), Global.NUMERICAL_TWO);
        //商品信息
        KwOrderUsualLandTransportGoods goods = orderGeneralTransportGoodsMapper.findByGoods(logisticsOrder.getId());

        /**MySql车辆运单数据处理/存储**/
        //List<SckwWaybillOrder> sckwWaybillOrders = new ArrayList();
        for (SendCarDto sendCarDto : params) {
            /**KwtWaybillOrder数据组装**/
            KwWaybillOrder waybillOrder = this.setKwtWaybillOrder(sendCarDto);
            /**数据存储**/
            if (sendCarDto.getType() == Global.NUMERICAL_ONE) {
                    //车辆运单存储
                    //String wOrderNo = getRedisGenerateWaybillOrderNo(RedisOrderGenerateEnum.WAYBILL_ORDER, OrderRuleEnum.WAYBILL_ORDER, logisticsOrder.getLOrderNo());
                    //waybillOrder.setId(null);
                    //waybillOrder.setWOrderNo(wOrderNo);

                    ranksSave(waybillOrder, loadAddress, unloadAddress, null);

                    /**SckwWaybillOrder数据组装**/
                    //SckwWaybillOrder mongoOrder = setSckwWaybillOrder(sendCarDto, waybillOrder, logisticsOrder, loadAddress,
                    //        unloadAddress, checkEnt, carrierEnt, goods);
                    //sckwWaybillOrders.add(mongoOrder);
            } else {
                //循环派车存储
                KwOrderUsualLandTransportCirculate circulate = circulateSave(waybillOrder);
                //if (circulate != null) {
                //    /**SckwWaybillOrder数据组装**/
                //    SckwWaybillOrder mongoOrder = setSckwWaybillOrder(sendCarDto, waybillOrder, logisticsOrder, loadAddress,
                //            unloadAddress, checkEnt, carrierEnt, goods);
                //    mongoOrder.set_id(circulate.getId());
                //    mongoOrder.setWOrderId(null);
                //    mongoOrder.setWOrderNo(null);
                //    sckwWaybillOrders.add(mongoOrder);
                //}
            }
        }

        /**Mongodb数据存储
         for (SckwWaybillOrder waybillOrder:sckwWaybillOrders) {
         //rabbitMq业务汇总数据发送/消费对象
         SckwBusSum busSum = new SckwBusSum();
         //业务汇总类型
         busSum.setBusSumType(BusinessTypeEnum.WAYBILL_ORDER_TYPE.getName());
         //操作对象（1新增/2修改/3替换数据）
         busSum.setMethod(1);
         //业务汇总数据对象
         busSum.setObject(waybillOrder);
         streamBridge.send("sckw-busSum", busSum);
         }**/

        return HttpResult.ok();
    }

    public void ranksSave(KwWaybillOrder waybillOrder, List<KwWaybillOrderAddress> loadAddressList,
                          List<KwWaybillOrderAddress> unloadAddressList, Date operateTime) {
        /**车辆运单信息**/
        waybillOrder.setId(new IdWorker(Global.NUMERICAL_ONE).nextId());
        kwWaybillOrderMapper.insert(waybillOrder);

        long orderId = waybillOrder.getId();

        /**车辆运单地址信息**/
        for (KwWaybillOrderAddress loadAddress : loadAddressList) {
            loadAddress.setOrderId(orderId);
            loadAddress.setLAddressId(loadAddress.getId());
            loadAddress.setId(null);
            kwWaybillOrderAddressMapper.insert(loadAddress);
        }

        for (KwWaybillOrderAddress unloadAddress : unloadAddressList) {
            unloadAddress.setOrderId(orderId);
            unloadAddress.setLAddressId(unloadAddress.getId());
            unloadAddress.setId(null);
            kwWaybillOrderAddressMapper.insert(unloadAddress);
        }

        /**车辆运单状态记录**/
        this.setWaybillOrderTrack(waybillOrder.getId(), operateTime != null ? operateTime : waybillOrder.getUpdateTime(),
                waybillOrder.getStatus(), null);
    }

    public KwWaybillOrderTrack setWaybillOrderTrack(Long wOrderId, Date operateTime, int status, String remark) {
        KwWaybillOrderTrack orderTrack = new KwWaybillOrderTrack();
        orderTrack.setTOrderId(wOrderId);
        orderTrack.setOperateTime(operateTime);
        orderTrack.setStatus(status);
        orderTrack.setRemark(remark);
        int count = kwWaybillOrderTrackMapper.insert(orderTrack);
        return count > 0 ? orderTrack : null;
    }

    public KwWaybillOrder setKwtWaybillOrder(SendCarDto sendCarDto) {
        KwWaybillOrder waybillOrder = new KwWaybillOrder();
        //waybillOrder.setEntId(LoginUserHolder.getEntId());
        //waybillOrder.setId(new IdWorker(Global.NUMERICAL_ONE).nextId());
        waybillOrder.setOrderId(sendCarDto.getOrderId());
        //waybillOrder.setStartTime(sendCarDto.get());
        //waybillOrder.setEndTime(sendCarDto.getUnloadDateTime());
        waybillOrder.setTruckId(sendCarDto.getTruckId());
        waybillOrder.setTruckNo(sendCarDto.getTruckNo());
        waybillOrder.setDriverId(sendCarDto.getDriverId());
        waybillOrder.setDriverName(sendCarDto.getDriverName());
        waybillOrder.setDriverPhone(sendCarDto.getDriverPhone());
        waybillOrder.setDriverIdcard(sendCarDto.getDriverIdcard());
        waybillOrder.setEntrustAmount(new BigDecimal(sendCarDto.getAmount()));
        waybillOrder.setUnloadAmount(new BigDecimal(Global.AMOUNT));
        waybillOrder.setLoadAmount(new BigDecimal(Global.AMOUNT));
        waybillOrder.setDeficitAmount(new BigDecimal(Global.AMOUNT));
        waybillOrder.setStatus(CarWaybillEnum.THREE.getCode());
        return waybillOrder;
    }

    public List<KwWaybillOrderAddress> getAddress(Long orderId, int addressType, int type) {
        /**查询数据**/
        List<KwWaybillOrderAddress> addressList = new ArrayList<>();

        if (type == Global.NUMERICAL_ONE) {
            List<KwOrderUsualLandTransportAddress> orderAddressList = kwOrderUsualLandTransportAddressMapper.findByAddress(orderId, addressType);
            orderAddressList.forEach(e -> {
                KwWaybillOrderAddress address = new KwWaybillOrderAddress();
                BeanUtils.copyProperties(e, address);
                addressList.add(address);
            });
        }

        if (type == Global.NUMERICAL_TWO) {
            KwWaybillOrderAddress orderAddress = kwWaybillOrderAddressMapper.findByAddress(orderId, addressType);
            if (orderAddress != null) {
                addressList.add(orderAddress);
            }
        }

        return addressList;
    }

    /**
     * @Description: 列表筛选统计
     * @Author: Lt
     * @Date: 2024/5/12 18:25
     */
    public List<Map<String, Object>> getStatusCountListInSingleQuery() {
        // 查询每个状态的计数
        List<Map<String, Object>> statusCounts = kwWaybillOrderMapper.countByStatus();

        // 将查询结果转换为所需的格式
        List<WayBillStatusEnum> sortedEnums = WayBillStatusEnum.getSortList();
        List<Map<String, Object>> result = new ArrayList<>();
        for (WayBillStatusEnum enumItem : sortedEnums) {
            Map<String, Object> statusCount = statusCounts.stream()
                    .filter(c -> enumItem.getCode().equals(c.get("status")))
                    .findFirst()
                    .orElseGet(() -> Map.of("status", enumItem.getCode(), "count", 0));
            result.add(
                    Map.of(
                            "key", enumItem.getMsg(),
                            "value", enumItem.getCode(),
                            "data", statusCount.get("count")
                    )
            );
        }
        return result;
    }


    @Transactional(rollbackFor = Exception.class)
    public HttpResult waybillTaking(String waybillId)
    {
        KwWaybillOrder kwWaybillOrder = kwWaybillOrderMapper.selectById(waybillId);
        if (Objects.isNull(kwWaybillOrder)) {
            return HttpResult.error("运单不存在");
        }
        if(!kwWaybillOrder.getStatus().equals(WayBillStatusEnum.ONE.getCode())) {
            return HttpResult.error("当前运单不是运输中状态");
        }
        if(kwWaybillOrder.getStatus().equals(WayBillStatusEnum.THREE.getCode())) {
            return HttpResult.error("当前运单已完成,请勿重复操作");
        }
        kwWaybillOrder.setStatus(WayBillStatusEnum.THREE.getCode());
        kwWaybillOrderMapper.updateById(kwWaybillOrder);

        //运单接单扣除剩余代运量
        KwOrder kwOrder = logisticsOrderDao.selectById(kwWaybillOrder.getOrderId());
        BigDecimal subtract = kwOrder.getRemainNum().subtract(kwWaybillOrder.getEntrustAmount());
        kwOrder.setRemainNum(subtract);
        logisticsOrderDao.updateById(kwOrder);
        //添加操作记录
        KwWaybillOrderTrack kwWaybillOrderTrack = new KwWaybillOrderTrack();
        kwWaybillOrderTrack.setTOrderId(Long.valueOf(waybillId));
        kwWaybillOrderTrack.setStatus(WayBillStatusEnum.FIVE.getCode());
        kwWaybillOrderTrackMapper.insert(kwWaybillOrderTrack);
        return HttpResult.ok("接单成功");
    }

    /**
     * @return
     * @Description: 运单完成
     * @Author: Lt
     * @Date: 2024/5/13 17:23
     */
    public HttpResult waybillFinish(WaybillFinishReq waybillFinishReq)
    {

        KwWaybillOrder kwWaybillOrder = kwWaybillOrderMapper.selectById(waybillFinishReq.getWaybillId());
         Long orderId = kwWaybillOrder.getOrderId();
        if (Objects.isNull(kwWaybillOrder)) {
            return HttpResult.error("运单不存在");
        }
        if(kwWaybillOrder.getStatus().equals(WayBillStatusEnum.FIVE.getCode())){
            return HttpResult.error("当前运单已完结,请勿重复操作");
        }
        if(!kwWaybillOrder.getStatus().equals(WayBillStatusEnum.THREE.getCode())) {
            return HttpResult.error("当前运单不是运输中状态");
        }
        //修改运单状态
        kwWaybillOrder.setStatus(WayBillStatusEnum.FIVE.getCode());
        kwWaybillOrder.setLoadAmount(waybillFinishReq.getLoadWeight());
        kwWaybillOrder.setUnloadAmount(waybillFinishReq.getUnLoadWeight());
        kwWaybillOrderMapper.updateById(kwWaybillOrder);
        //订单累加
        KwOrder kwOrder = logisticsOrderDao.selectById(orderId);
        BigDecimal totalLoadAmount = kwOrder.getTotalLoadAmount().add(waybillFinishReq.getLoadWeight());
        BigDecimal totalUnLoadAmount = kwOrder.getTotalUnloadAmount().add(waybillFinishReq.getUnLoadWeight());

        kwOrder.setId(orderId).setTotalLoadAmount(totalLoadAmount).setTotalUnloadAmount(totalUnLoadAmount);
        logisticsOrderDao.updateById(kwOrder);

        //添加记录
        KwWaybillOrderFinish kwWaybillOrderFinish = new KwWaybillOrderFinish();
        kwWaybillOrderFinish.setId(new IdWorker(1L).nextId());
        kwWaybillOrderFinish.setWaybillId(waybillFinishReq.getWaybillId());
        kwWaybillOrderFinish.setLoadTime(waybillFinishReq.getLoadTime());
        kwWaybillOrderFinish.setUnloadTime(waybillFinishReq.getUnloadTime());
        kwWaybillOrderFinish.setLoadWeight(waybillFinishReq.getLoadWeight());
        kwWaybillOrderFinish.setUnloadWeight(waybillFinishReq.getUnLoadWeight());
        kwWaybillOrderFinishMapper.insert(kwWaybillOrderFinish);
        return HttpResult.ok("完结成功");
    }


}
