package com.sckw.transport.service.app;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sckw.contract.api.RemoteContractService;
import com.sckw.core.common.enums.enums.ErrorCodeEnum;
import com.sckw.core.exception.BusinessPlatfromException;
import com.sckw.core.model.constant.Global;
import com.sckw.core.model.enums.CarWaybillV1Enum;
import com.sckw.core.model.enums.GatekeeperStatusEnum;
import com.sckw.core.model.enums.GatekeeperTypeEnum;
import com.sckw.core.utils.CollectionUtils;
import com.sckw.core.utils.DateUtils;
import com.sckw.core.utils.StringUtils;
import com.sckw.core.web.response.result.PageDataResult;
import com.sckw.order.api.dubbo.TradeOrderInfoService;
import com.sckw.order.api.model.OrderUnitInfoDetailVO;
import com.sckw.product.api.dubbo.GoodsInfoService;
import com.sckw.system.api.RemoteSystemService;
import com.sckw.transport.model.*;
import com.sckw.transport.model.enuma.WeighbridgeTypeEnum;
import com.sckw.transport.model.param.forklift.reponse.GatekeeperOrderResp;
import com.sckw.transport.model.param.forklift.request.GatekeeperOrderPassParam;
import com.sckw.transport.model.param.forklift.request.GatekeeperOrderQueryParam;
import com.sckw.transport.model.vo.StatisticsWaybillResp;
import com.sckw.transport.repository.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * Author: donglang
 * Time: 2026-01-05
 * Des: 铲车司机Service
 * Version: 1.0
 */

@Slf4j
@Service
@RequiredArgsConstructor
public class GatekeeperOrderService {


    private final KwtGatekeeperWaybillOrderRepository gatekeeperWaybillOrderRepository;

    private final KwtWaybillOrderRepository waybillOrderRepository;
    private final KwtWaybillOrderSubtaskRepository waybillOrderSubtaskRepository;
    private final KwtWaybillOrderTicketRepository waybillOrderTicketRepository;
    private final KwtLogisticsOrderRepository logisticsOrderRepository;
    private final KwtLogisticsOrderGoodsRepository logisticsOrderGoodsRepository;
    private final KwtWaybillOrderNodeRepository waybillOrderNodeRepository;
    private final KwtWaybillOrderWeighbridgeRepository waybillOrderWeighbridgeRepository;

    @DubboReference(version = "1.0.0", group = "design", check = false)
    private RemoteContractService remoteContractService;

    @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 80000)
    TradeOrderInfoService tradeOrderInfoService;

    @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 6000)
   RemoteSystemService remoteSystemService;

    @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 6000)
    GoodsInfoService goodsInfoService;


    @Autowired
    WaybillOrderService waybillOrderService;

    /**
     * 分页查询门卫订单
     * @param param
     * @return
     */
    public PageDataResult<GatekeeperOrderResp> pageQueryGatekeeperOrder(GatekeeperOrderQueryParam param) {
        log.info("查询门卫订单：{}", JSON.toJSONString(param));
        if (param.getStatus() == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "状态不能为空！");
        }
        //构建查询条件
        LambdaQueryWrapper<KwtGatekeeperWaybillOrder> wrapper = buildAndExecuteQuery(param);

        //查询门卫订单
        Page<KwtGatekeeperWaybillOrder> pageByStatus = gatekeeperWaybillOrderRepository.page(new Page<>(param.getPageNum(), param.getPageSize()), wrapper);
        List<KwtGatekeeperWaybillOrder> records = pageByStatus.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            log.info("当前无运单订单信息");
            return PageDataResult.empty(param.getPageNum(), param.getPageSize());
        }
        List<GatekeeperOrderResp> gatekeeperOrderPageResult = getGatekeeperOrderPageResult(records);
        //处理异常车辆数据
        gatekeeperOrderPageResult = filterGatekeeperOrderResp(param, gatekeeperOrderPageResult);

        //排序
        sort(param, gatekeeperOrderPageResult);
        return PageDataResult.success(param.getPageNum(), param.getPageSize(), pageByStatus.getTotal(), gatekeeperOrderPageResult);
    }

    /**
     * 构建查询条件并执行分页查询
     */
    private LambdaQueryWrapper<KwtGatekeeperWaybillOrder> buildAndExecuteQuery(GatekeeperOrderQueryParam param) {
        //基础查询条件
        LambdaQueryWrapper<KwtGatekeeperWaybillOrder> queryWrapper = buildBaseQueryWrapper(param);

        //模糊查询条件
        handleSearchKeyword(param, queryWrapper);
        return queryWrapper;

    }

    /**
     * 构建基础查询条件
     * @param param
     * @return
     */
    private  LambdaQueryWrapper<KwtGatekeeperWaybillOrder> buildBaseQueryWrapper(GatekeeperOrderQueryParam param) {
        LambdaQueryWrapper<KwtGatekeeperWaybillOrder> wrapper = Wrappers.<KwtGatekeeperWaybillOrder>lambdaQuery()
                .orderByDesc(KwtGatekeeperWaybillOrder::getCreateTime)
                .orderByDesc(KwtGatekeeperWaybillOrder::getId);
        //待进场
        if (param.getStatus() == 1) {
            wrapper.eq(KwtGatekeeperWaybillOrder::getStatus, GatekeeperStatusEnum.PENDING_ENTRY.getCode());
            //待离场
        } else if (param.getStatus() == 2) {
            wrapper.in(KwtGatekeeperWaybillOrder::getStatus,
                    GatekeeperStatusEnum.PENDING_RELEASE.getCode(),
                    GatekeeperStatusEnum.READY_RELEASE.getCode());
            //场内车辆，状态为4是：处理场内异常车辆逻辑
        } else if (param.getStatus() == 3 || param.getStatus() == 4) {
            wrapper.in(KwtGatekeeperWaybillOrder::getStatus,
                    GatekeeperStatusEnum.IN_YARD.getCode(),
                    GatekeeperStatusEnum.PENDING_RELEASE.getCode(),
                    GatekeeperStatusEnum.READY_RELEASE.getCode());
            //出入记录
        } else if (param.getStatus() == 5) {
            wrapper.in(KwtGatekeeperWaybillOrder::getStatus,
                    GatekeeperStatusEnum.EXITED.getCode());
        }
        return wrapper;
    }

    /**
     * 关键词模糊查询
     */
    private void handleSearchKeyword(GatekeeperOrderQueryParam param, LambdaQueryWrapper<KwtGatekeeperWaybillOrder> wrapper) {
        if (StringUtils.isBlank(param.getKeyWords())) {
            return;
        }
        Set<Long> matchedWaybillOrderIds = findMatchedGatekeeperOrderIds(param);
        if (CollectionUtils.isEmpty(matchedWaybillOrderIds)) {
            log.info("模糊查询无匹配结果，关键词：{}", param.getKeyWords());
            // 设置一个不可能的条件，确保返回空结果
            wrapper.eq(KwtGatekeeperWaybillOrder::getId, Global.MINUS_ONE);
        } else {
            wrapper.in(KwtGatekeeperWaybillOrder::getId, matchedWaybillOrderIds);
        }
    }

    /**
     * 查询匹配的运单ID（以铲车ID为主键）
     */
    private Set<Long> findMatchedGatekeeperOrderIds(GatekeeperOrderQueryParam param) {
        Set<Long> gatekeeperOrderIds = ConcurrentHashMap.newKeySet();;
        List<Runnable> searchTasks = Arrays.asList(
                //1. 运单编号查询（主表字段，直接匹配）
                () -> addMatchedIds(gatekeeperOrderIds, param),

                //2. 车牌号、司机姓名查询
                () -> addMatchedIdsFromWaybillNo(gatekeeperOrderIds, param),

                // 3. 客户名称查询
                () -> addMatchedIdsFromLogisticsOrderNo(gatekeeperOrderIds, param)
        );
        // 使用并行流执行查询任务
        searchTasks.parallelStream().forEach(Runnable::run);
        return gatekeeperOrderIds;
    }

    /**
     * 运单编号查询
     * @param gatekeeperOrderIds
     * @param param
     */
    private void addMatchedIds(Set<Long> gatekeeperOrderIds, GatekeeperOrderQueryParam param) {
        // 1. 运单编号查询（主表字段，直接匹配）
        List<KwtGatekeeperWaybillOrder> gatekeeperWaybillOrder = gatekeeperWaybillOrderRepository.list(
                Wrappers.<KwtGatekeeperWaybillOrder>lambdaQuery()
                        .like(KwtGatekeeperWaybillOrder::getWOrderNo, param.getKeyWords())
        );
        gatekeeperOrderIds.addAll(gatekeeperWaybillOrder.stream()
                .map(KwtGatekeeperWaybillOrder::getId)
                .collect(Collectors.toSet()));
    }

    /**
     * 车牌号、司机姓名查询
     * @param gatekeeperOrderIds
     * @param param
     */
    private void addMatchedIdsFromWaybillNo(Set<Long> gatekeeperOrderIds, GatekeeperOrderQueryParam param) {
        List<KwtWaybillOrder> waybillOrders = waybillOrderRepository.list(
                Wrappers.<KwtWaybillOrder>lambdaQuery()
                        .like(KwtWaybillOrder::getTruckNo, param.getKeyWords())
                        .or()
                        .like(KwtWaybillOrder::getDriverName, param.getKeyWords())
                        .eq(KwtWaybillOrder::getDelFlag, 0)
        );
        if (CollectionUtils.isNotEmpty(waybillOrders)) {
            List<Long> matchedWaybillOrderIds = waybillOrders.stream()
                    .map(KwtWaybillOrder::getId)
                    .collect(Collectors.toList());

            // 查询这些物流运单对应的铲车订单
            List<KwtGatekeeperWaybillOrder> gatekeeperOrderList = gatekeeperWaybillOrderRepository
                    .queryGatekeeperWaybillOrderByWOrderIds(matchedWaybillOrderIds);

            gatekeeperOrderIds.addAll(gatekeeperOrderList.stream()
                    .map(KwtGatekeeperWaybillOrder::getId)
                    .collect(Collectors.toSet()));
        }
    }


    /**
     * 从企业名称查询贸易订单关联的铲车订单
     */
    private void addMatchedIdsFromLogisticsOrderNo(Set<Long> gatekeeperOrderIds, GatekeeperOrderQueryParam param) {
        // 从企业名称查询贸易订单
        List<OrderUnitInfoDetailVO> orderUnitInfoDetailVOS = tradeOrderInfoService.queryOrderUnitInfByEntName(param.getKeyWords());

        if (CollectionUtils.isEmpty(orderUnitInfoDetailVOS)) {
            return;
        }
        Set<Long> tOrderIds = orderUnitInfoDetailVOS.stream()
                .map(OrderUnitInfoDetailVO::getTOrderId)
                .collect(Collectors.toSet());

        // 通过贸易订单查询关联的物流订单
        List<KwtLogisticsOrder> logisticsOrders = logisticsOrderRepository.queryByTradeOrderIds(tOrderIds);
        if (CollectionUtils.isNotEmpty(logisticsOrders)) {
            List<Long> logOrderIds = logisticsOrders.stream()
                    .map(KwtLogisticsOrder::getId)
                    .collect(Collectors.toList());

            // 查询这些物流订单对应的铲车订单
            List<KwtGatekeeperWaybillOrder> gatekeeperOrderList = gatekeeperWaybillOrderRepository
                    .queryGatekeeperWaybillOrderByLogOrderIds(logOrderIds);

            gatekeeperOrderIds.addAll(gatekeeperOrderList.stream()
                    .map(KwtGatekeeperWaybillOrder::getId)
                    .collect(Collectors.toSet()));
        }

    }

    /**
     * 获取门卫订单数据
     * @param records
     * @return
     */
    private List<GatekeeperOrderResp> getGatekeeperOrderPageResult(List<KwtGatekeeperWaybillOrder> records) {
        Set<Long> wOrderIds = records.stream().map(KwtGatekeeperWaybillOrder::getWOrderId).filter(Objects::nonNull).collect(Collectors.toSet());
        //查询运单
        List<KwtWaybillOrder> waybillOrders = waybillOrderRepository.queryByBillOrderIds(wOrderIds);
        if (CollectionUtils.isEmpty(waybillOrders)) {
            log.info("【门卫】无物流运单信息，运单id:{}", JSON.toJSONString(wOrderIds));
            return Collections.emptyList();
        }
        Map<Long, KwtWaybillOrder> waybillOrderMap = waybillOrders.stream()
                .collect(Collectors.toMap(KwtWaybillOrder::getId, Function.identity(), (x, y) -> x));
        Set<Long> lOrderIds = waybillOrders.stream().map(KwtWaybillOrder::getLOrderId).collect(Collectors.toSet());

        //查询运单装卸货
        List<KwtWaybillOrderTicket> waybillOrderTickets = waybillOrderTicketRepository.queryByWOrderIds(new ArrayList<>(wOrderIds));
        if (CollectionUtils.isEmpty(waybillOrderTickets)) {
            log.info("【门卫】无运单装卸货信息，运单id:{}", JSON.toJSONString(wOrderIds));
            return Collections.emptyList();
        }
        Map<String, KwtWaybillOrderTicket> waybillOrderTicketMap = waybillOrderTickets.stream()
                .collect(Collectors.toMap(ticket -> ticket.getWOrderId() + "-" + ticket.getType(), Function.identity(), (x, y) -> x));

        //查询物流订单
        List<KwtLogisticsOrder> logisticsOrder = logisticsOrderRepository.queryByLogOrderIds(lOrderIds);
        if (CollectionUtils.isEmpty(logisticsOrder)) {
            log.info("【门卫】无物流订单信息，物流订单id:{}", JSON.toJSONString(lOrderIds));
            return Collections.emptyList();
        }
        Map<Long, KwtLogisticsOrder> logisticsOrderMap = logisticsOrder.stream().collect(Collectors.toMap(KwtLogisticsOrder::getId, Function.identity(), (x, y) -> x));
        Set<Long> tOrderIds = logisticsOrder.stream().map(KwtLogisticsOrder::getTOrderId).collect(Collectors.toSet());

        //查询贸易订单企业信息
        List<OrderUnitInfoDetailVO> orderUnitInfoDetailVOS = tradeOrderInfoService.queryOrderUnitInfByTOrderId(tOrderIds);
        if (CollectionUtils.isEmpty(orderUnitInfoDetailVOS)) {
            log.info("【门卫】无订单企业信息，物流订单id:{}", JSON.toJSONString(lOrderIds));
            return Collections.emptyList();
        }
        Map<String, OrderUnitInfoDetailVO> tradeOrderAndUnit = orderUnitInfoDetailVOS.stream().collect(Collectors.toMap(unit -> unit.getTOrderId() + "-" + unit.getUnitType(), Function.identity(), (x, y) -> x));

        //组装铲车订单数据
        return records.stream()
                .map(gatekeeperWaybillOrder -> buildGatekeeperOrderResp(gatekeeperWaybillOrder, waybillOrderMap, waybillOrderTicketMap, logisticsOrderMap, tradeOrderAndUnit))
                .collect(Collectors.toList());
    }

    /**
     * 组装门卫订单信息
     * @param gatekeeperWaybillOrder
     * @param waybillOrderMap

     * @return
     */
    private GatekeeperOrderResp buildGatekeeperOrderResp(KwtGatekeeperWaybillOrder gatekeeperWaybillOrder,
                                                     Map<Long, KwtWaybillOrder> waybillOrderMap,
                                                     Map<String, KwtWaybillOrderTicket> waybillOrderTicketMap,
                                                     Map<Long, KwtLogisticsOrder> logisticsOrderMap,
                                                     Map<String, OrderUnitInfoDetailVO> tradeOrderAndUnit) {

        GatekeeperOrderResp gatekeeper = new GatekeeperOrderResp();
        gatekeeper.setId(gatekeeperWaybillOrder.getId());
        gatekeeper.setEntId(gatekeeperWaybillOrder.getEntId());
        gatekeeper.setWaybillOrderNo(gatekeeperWaybillOrder.getWOrderNo());
        gatekeeper.setWaybillOrderId(gatekeeperWaybillOrder.getWOrderId());
        gatekeeper.setLogisticsOrderId(gatekeeperWaybillOrder.getLOrderId());
        gatekeeper.setStatus(gatekeeperWaybillOrder.getStatus());
        gatekeeper.setType(gatekeeperWaybillOrder.getType());
        gatekeeper.setTypeDesc(GatekeeperTypeEnum.getDesc(gatekeeperWaybillOrder.getType()));
        String statusDesc = Objects.equals(gatekeeperWaybillOrder.getType(), GatekeeperTypeEnum.LOADING.getCode())
                ? GatekeeperStatusEnum.getDesc(gatekeeperWaybillOrder.getStatus())
                : GatekeeperStatusEnum.getDescription(gatekeeperWaybillOrder.getStatus());
        gatekeeper.setStatusDesc(statusDesc);
        gatekeeper.setCarAxisName(gatekeeperWaybillOrder.getCarAxis());
        gatekeeper.setLegalLoad(gatekeeperWaybillOrder.getLegalLoad());
        gatekeeper.setTruckType(gatekeeperWaybillOrder.getTruckType());
        gatekeeper.setIntoTime(gatekeeperWaybillOrder.getIntoTime());
        gatekeeper.setLeaveTime(gatekeeperWaybillOrder.getLeaveTime());
        gatekeeper.setWaybillAcceptTime(gatekeeperWaybillOrder.getWaybillAcceptTime());
        gatekeeper.setEntrustAmount(gatekeeperWaybillOrder.getEntrustAmount());
        gatekeeper.setGoodsId(gatekeeperWaybillOrder.getGoodsId());
        gatekeeper.setGoodsName(gatekeeperWaybillOrder.getGoodsName());
        gatekeeper.setRemark(gatekeeperWaybillOrder.getRemark());

        //运单数据
        KwtWaybillOrder waybillOrder = waybillOrderMap.getOrDefault(gatekeeperWaybillOrder.getWOrderId(), new KwtWaybillOrder());
        gatekeeper.setTruckId(waybillOrder.getTruckId());
        gatekeeper.setTruckNo(waybillOrder.getTruckNo());
        gatekeeper.setName(waybillOrder.getDriverName());
        gatekeeper.setPhone(waybillOrder.getDriverPhone());
        gatekeeper.setIdCard(waybillOrder.getDriverIdcard());

        //采购企业信息
        KwtLogisticsOrder logisticsOrder = logisticsOrderMap.getOrDefault(waybillOrder.getLOrderId(), new KwtLogisticsOrder());
        OrderUnitInfoDetailVO orderUnit = tradeOrderAndUnit.getOrDefault(logisticsOrder.getTOrderId() + "-" + 1, new OrderUnitInfoDetailVO());
        gatekeeper.setPrEntId(orderUnit.getEntId());
        gatekeeper.setPrEntName(orderUnit.getFirmName());


        //装卸货信息
        KwtWaybillOrderTicket ticket = waybillOrderTicketMap.getOrDefault(gatekeeperWaybillOrder.getWOrderId() + "-" + 1, new KwtWaybillOrderTicket());
        gatekeeper.setTareAmount(ticket.getTareAmount());
        gatekeeper.setGrossAmount(ticket.getGrossAmount());

        return gatekeeper;
    }

    /**
     * 处理异常车辆数据
     * @param param
     * @param gatekeeperOrderPageResult
     * @return
     */
    private static List<GatekeeperOrderResp> filterGatekeeperOrderResp(GatekeeperOrderQueryParam param, List<GatekeeperOrderResp> gatekeeperOrderPageResult) {
        double configHours = 3;
        //处理异常车辆数据
        if (param.getStatus() != 4) {
            return gatekeeperOrderPageResult;
        }
        return gatekeeperOrderPageResult.stream().filter(order -> {
            if (order.getIntoTime() == null) {
                return false;
            }
            // 计算已停留小时数
            double stayHours = DateUtils.hoursBetween(order.getIntoTime(), new Date());
            order.setDurationTime(stayHours);
            return stayHours > configHours;
        }).collect(Collectors.toList());
    }

    /**
     * 排序
     * @param param
     * @param gatekeeperOrderPageResult
     */
    private void sort(GatekeeperOrderQueryParam param, List<GatekeeperOrderResp> gatekeeperOrderPageResult) {
        if (CollectionUtils.isEmpty(gatekeeperOrderPageResult)) {
            return;
        }
        // 根据状态进行排序
        switch (param.getStatus()) {
            case 1:
                // 待进场: 运输司机接单时间升序
                gatekeeperOrderPageResult.sort(Comparator.comparing(GatekeeperOrderResp::getWaybillAcceptTime));
                break;
            case 2:
                // 待离场:先按照待离场展示，后按照空载待离场和已放行未离场展示，在按照状态变更时间升序
                gatekeeperOrderPageResult.sort(
                        Comparator.comparing((GatekeeperOrderResp order) -> {
                                    // 状态为空时，也排到后面
                                    return order.getStatus() == null || order.getStatus() != 10;
                                })
                                // 时间为空的排最后
                                .thenComparing(
                                        GatekeeperOrderResp::getUpdateTime,
                                        Comparator.nullsLast(Comparator.naturalOrder())
                                )
                );
                break;
            case 3:
                // 场内车辆: 车辆进场时间升序
                gatekeeperOrderPageResult.sort(Comparator.comparing(GatekeeperOrderResp::getIntoTime));
                break;
            case 4:
                // 异常车辆: 场内耗时倒序
                gatekeeperOrderPageResult.sort(Comparator.comparing(GatekeeperOrderResp::getDurationTime).reversed());
                break;
            case 5:
                // 出入记录: 离场时间倒序
                gatekeeperOrderPageResult.sort(Comparator.comparing(GatekeeperOrderResp::getLeaveTime).reversed());
                break;
            default:
                break;
        }
    }


    /**
     * 铲车订单状态统计
     * @param param
     * @return
     */
    public StatisticsWaybillResp statisticsGatekeeperOrder(GatekeeperOrderQueryParam param) {
        log.info("铲车订单状态统计：{}", JSON.toJSONString(param));
        StatisticsWaybillResp resp = new StatisticsWaybillResp();

        LambdaQueryWrapper<KwtGatekeeperWaybillOrder> wrapper = Wrappers.<KwtGatekeeperWaybillOrder>lambdaQuery()
                .orderByDesc(KwtGatekeeperWaybillOrder::getCreateTime);

        //查询门卫订单
        List<KwtGatekeeperWaybillOrder> orderList = gatekeeperWaybillOrderRepository.list(wrapper);
        if (CollectionUtils.isEmpty(orderList)) {
            log.info("当前无门卫统计记录，统计结果为空");
            resp.setOrderStatusStatistics(buildDefaultStatusStatistics());
            return resp;
        }
        List<GatekeeperOrderResp> gatekeeperOrderPageResult = getGatekeeperOrderPageResult(orderList);
        resp.setOrderStatusStatistics(calculateStatusStatistics(gatekeeperOrderPageResult));
        return resp;

    }

    /**
     * 构建默认的状态统计列表（三种状态，数量均为0）
     * @return 默认统计列表
     */
    private List<StatisticsWaybillResp.OrderBillStatusStatistics> buildDefaultStatusStatistics() {
        List<StatisticsWaybillResp.OrderBillStatusStatistics> defaultList = new ArrayList<>();
        // 待进场
        StatisticsWaybillResp.OrderBillStatusStatistics pendingEntry = new StatisticsWaybillResp.OrderBillStatusStatistics();
        pendingEntry.setOrderStatus("1");
        pendingEntry.setOrderStatusDesc("待进场");
        pendingEntry.setOrderNum("0");
        defaultList.add(pendingEntry);
        // 待离场
        StatisticsWaybillResp.OrderBillStatusStatistics pendingExit = new StatisticsWaybillResp.OrderBillStatusStatistics();
        pendingExit.setOrderStatus("2");
        pendingExit.setOrderStatusDesc("待离场");
        pendingExit.setOrderNum("0");
        defaultList.add(pendingExit);
        // 场内车辆
        StatisticsWaybillResp.OrderBillStatusStatistics inPark = new StatisticsWaybillResp.OrderBillStatusStatistics();
        inPark.setOrderStatus("3");
        inPark.setOrderStatusDesc("场内车辆");
        inPark.setOrderNum("0");
        defaultList.add(inPark);
        // 异常车辆
        StatisticsWaybillResp.OrderBillStatusStatistics isAbnormal = new StatisticsWaybillResp.OrderBillStatusStatistics();
        isAbnormal.setOrderStatus("4");
        isAbnormal.setOrderStatusDesc("异常车辆");
        isAbnormal.setOrderNum("0");
        defaultList.add(isAbnormal);

        return defaultList;
    }

    /**
     * 计算运单状态统计
     * @param gatekeeperOrderList
     * @return
     */
    private static List<StatisticsWaybillResp.OrderBillStatusStatistics> calculateStatusStatistics(List<GatekeeperOrderResp> gatekeeperOrderList) {
        //车辆停留超时配置
        double configHours = 2000;

        // 定义状态码聚合规则
        Map<String[], List<String>> aggregateRules = Map.of(
                new String[]{"1", "待进场"}, Arrays.asList("1"),
                new String[]{"2", "待离场"}, Arrays.asList("10", "15"),
                new String[]{"3", "场内车辆"}, Arrays.asList("5", "10", "15"),
                new String[]{"4", "异常车辆"}, Arrays.asList("5", "10", "15")
        );

        // 按原始状态统计数量
        Map<String, Long> statusCountMap = gatekeeperOrderList.stream()
                .collect(Collectors.groupingBy(va ->String.valueOf(va.getStatus()), Collectors.counting()));

        // 进行状态聚合
        List<StatisticsWaybillResp.OrderBillStatusStatistics> aggregatedList = aggregateRules.entrySet().stream()
                .map(rule -> {
                    String[] aggregateInfo = rule.getKey();
                    List<String> originalStatuses = rule.getValue();
                    long totalNum = 0;

                    // 处理状态为4的异常车辆
                    if (Objects.equals(aggregateInfo[0],"4")) {
                        totalNum = gatekeeperOrderList.stream().filter(order -> {
                            // 1. 必须包含在定义的异常状态源中 (5,10,15)
                            if (!originalStatuses.contains(String.valueOf(order.getStatus()))) {
                                return false;
                            }
                            // 2. 进场时间不为空
                            if (order.getIntoTime() == null) {
                                return false;
                            }
                            // 3. 计算停留时长
                            double stayHours = DateUtils.hoursBetween(order.getIntoTime(), new Date());
                            return stayHours > configHours;
                        }).count();
                    } else {
                        // 汇总对应状态的数量
                        totalNum = originalStatuses.stream()
                                .mapToLong(status -> statusCountMap.getOrDefault(status, 0L))
                                .sum();
                    }

                    // 构建聚合结果对象
                    StatisticsWaybillResp.OrderBillStatusStatistics aggregateStat = new StatisticsWaybillResp.OrderBillStatusStatistics();
                    aggregateStat.setOrderStatus(aggregateInfo[0]); // 聚合状态编码
                    aggregateStat.setOrderStatusDesc(aggregateInfo[1]); // 聚合状态描述
                    aggregateStat.setOrderNum(String.valueOf(totalNum)); // 汇总数量
                    return aggregateStat;
                })
                .sorted(Comparator.comparing(StatisticsWaybillResp.OrderBillStatusStatistics::getOrderStatus))
                .collect(Collectors.toList());
        return aggregatedList;
    }



    /**
     * 门卫放行
     * @param param
     * @return
     */
    public void pass(GatekeeperOrderPassParam param) {
        log.info("门卫放行：{}", JSON.toJSONString(param));
        KwtGatekeeperWaybillOrder gatekeeper = gatekeeperWaybillOrderRepository.getById(param.getId());
        if (gatekeeper == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.FORKLIFT_ORDER_NOT_FOUND, "当前门卫订单不存在！");
        }
        //1. 更改门卫状态为：已放行
        updateGatekeeperOrderStatus(gatekeeper, param);

        //2. 更改司机状态为：已放行未离场
        updateWaybillOrderStatus(gatekeeper, param);
    }

    /**
     * 更改门卫状态为：已放行
     * @param gatekeeper
     */
    private void updateGatekeeperOrderStatus(KwtGatekeeperWaybillOrder gatekeeper, GatekeeperOrderPassParam param) {
        if (!GatekeeperStatusEnum.PENDING_RELEASE.getCode().equals(gatekeeper.getStatus())) {
            throw new BusinessPlatfromException(ErrorCodeEnum.FORKLIFT_ORDER_STATUS_ERROR, "当前门卫订单状态异常，不能放行！");
        }
        //门卫放行后状态更改为：已放行
        gatekeeper.setStatus(GatekeeperStatusEnum.READY_RELEASE.getCode());
        gatekeeper.setLeaveTime(new Date());
        gatekeeper.setGatekeeperUserId(param.getGatekeeperUserId());
        gatekeeper.setGatekeeperName(param.getGatekeeperName());
        gatekeeper.setUpdateUser(param.getGatekeeperUserId());
        gatekeeperWaybillOrderRepository.updateById(gatekeeper);
    }

    /**
      * 更改司机状态为：已放行未离场
     * @param gatekeeper
     */
    private void updateWaybillOrderStatus(KwtGatekeeperWaybillOrder gatekeeper, GatekeeperOrderPassParam param) {
        // 1. 修改运单状态：已放行未离场
        updateWaybillStatus(gatekeeper);

        // 2. 修改子运单状态：已放行未离场
        updateWaybillSubtaskStatus(gatekeeper);

        // 3.创建运单轨迹日日志
        creatWaybillOrderNode(gatekeeper, param);
    }

    /**
     * 修改运单状态
     * @param gatekeeper
     */
    private void updateWaybillStatus(KwtGatekeeperWaybillOrder gatekeeper) {
        KwtWaybillOrder waybillOrder = waybillOrderRepository.getById(gatekeeper.getWOrderId());
        if (waybillOrder == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.FORKLIFT_ORDER_NOT_FOUND, "当前运单数据不存在！");
        }

        //装货单
        if (Objects.equals(gatekeeper.getType(), GatekeeperTypeEnum.LOADING.getCode())) {
            if (!CarWaybillV1Enum.WAIT_RELEASE.getCode().equals(waybillOrder.getStatus())) {
                throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "当前运单状态异常，不能推进为已放行待离场！");
            }
            waybillOrder.setStatus(CarWaybillV1Enum.RELEASED_NOT_EXITED.getCode());
        } else {
            //卸货单校验
            if (!CarWaybillV1Enum.UNLOADING_WAIT_RELEASE.getCode().equals(waybillOrder.getStatus())) {
                throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "当前运单状态异常，不能推进为已完成！");
            }
            waybillOrder.setStatus(CarWaybillV1Enum.COMPLETED.getCode());
        }
        waybillOrderRepository.updateById(waybillOrder);
    }

    /**
     * 修改子运单状态
     * @param gatekeeper
     */
    private void updateWaybillSubtaskStatus(KwtGatekeeperWaybillOrder gatekeeper) {
        KwtWaybillOrderSubtask waybillSubtask = waybillOrderSubtaskRepository.queryByWOrderId(gatekeeper.getWOrderId());
        if (waybillSubtask == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_SUB_NOT_FOUND, "未找到关联的子运单！");
        }
        //装货单
        if (Objects.equals(gatekeeper.getType(), GatekeeperTypeEnum.LOADING.getCode())) {
            if (!CarWaybillV1Enum.WAIT_RELEASE.getCode().equals(waybillSubtask.getStatus())) {
                throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "当前子运单状态异常，不能推进为已放行待离场！");
            }
            waybillSubtask.setStatus(CarWaybillV1Enum.RELEASED_NOT_EXITED.getCode());
        } else {
            //卸货单校验
            if (!CarWaybillV1Enum.UNLOADING_WAIT_RELEASE.getCode().equals(waybillSubtask.getStatus())) {
                throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "当前子运单状态异常，不能推进为已完成！");
            }
            waybillSubtask.setStatus(CarWaybillV1Enum.COMPLETED.getCode());
        }
        waybillOrderSubtaskRepository.updateById(waybillSubtask);
    }

    /**
     * 创建日子轨迹记录
     * @param gatekeeper
     * @return
     */
    public void creatWaybillOrderNode(KwtGatekeeperWaybillOrder gatekeeper, GatekeeperOrderPassParam param) {
        log.info("[门卫放行]创建车辆运单-节点轨迹入参参数：{}", JSON.toJSONString(gatekeeper));
        // 查询运单
        KwtWaybillOrder waybillOrder = waybillOrderRepository.getById(gatekeeper.getWOrderId());
        if (waybillOrder == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_SUB_NOT_FOUND, "未找到关联的运单！");
        }
        // 查询子运单
        KwtWaybillOrderSubtask subtask = waybillOrderSubtaskRepository.queryByWOrderId(gatekeeper.getWOrderId());
        if (subtask == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_SUB_NOT_FOUND, "未找到关联的子运单！");
        }
        //校验是否有卸货过磅记录
        List<KwtWaybillOrderWeighbridge> weighbridges = waybillOrderWeighbridgeRepository
                .queryWaybillOrderWeighbridgeByWOrderId(gatekeeper.getWOrderId(), WeighbridgeTypeEnum.UNLOADING.getCode());
        if (CollectionUtils.isEmpty(weighbridges)) {
            // 创建门卫放行记录
            String remark = "门卫[" + param.getGatekeeperName() + "]已放行";
            creatPassLogo(subtask, waybillOrder, remark);
        } else {
            // 1.创建门卫放行记录
            String remark1 = "门卫[" + param.getGatekeeperName() + "]已放行";
            creatPassLogo(subtask, waybillOrder, remark1);

            // 2.创建车辆离场放行记录
            String remark2 = "车辆[" + waybillOrder.getTruckNo() + "]已离场";
            creatPassLogo(subtask, waybillOrder, remark2);

            // 3.创建运单完成放行记录
            String remark3 = "运单[" + waybillOrder.getWOrderNo() + "]已完成";
            creatPassLogo(subtask, waybillOrder, remark3);

        }

    }

    /**
     * 记录门卫放行记录
     * @param subtask
     * @param waybillOrder
     */
    private void creatPassLogo(KwtWaybillOrderSubtask subtask, KwtWaybillOrder waybillOrder,String remark) {
        KwtWaybillOrderNode node = new KwtWaybillOrderNode();
        node.setWOrderId(waybillOrder.getId());
        node.setWSubtaskId(subtask.getId());
        node.setOrderStatus(subtask.getStatus());
        node.setTruckId(waybillOrder.getTruckId());
        node.setDriverId(waybillOrder.getDriverId());
        node.setDriverName(waybillOrder.getDriverName());
        node.setRemark(remark);
        waybillOrderNodeRepository.save(node);
        log.info("[门卫放行]记录节点轨迹成功，节点ID：{}", node.getId());
    }


}
