package com.sckw.transport.service.app;


import com.alibaba.fastjson.JSON;
import com.sckw.core.model.constant.Global;
import com.sckw.core.model.enums.CarWaybillV1Enum;
import com.sckw.core.model.enums.GatekeeperStatusEnum;
import com.sckw.order.api.dubbo.TradeOrderInfoService;
import com.sckw.transport.model.KwtGatekeeperWaybillOrder;
import com.sckw.transport.model.KwtLogisticsOrder;
import com.sckw.transport.model.KwtWaybillOrderSubtask;
import com.sckw.transport.model.param.SalesWaybillOrderQueryParam;
import com.sckw.transport.model.param.SalesWaybillOrderResp;
import com.sckw.transport.model.param.WaybillOrderReq;
import com.sckw.transport.model.vo.StatisticsWaybillResp;
import com.sckw.transport.repository.KwtGatekeeperWaybillOrderRepository;
import com.sckw.transport.repository.KwtLogisticsOrderRepository;
import com.sckw.transport.repository.KwtWaybillOrderSubtaskRepository;
import com.sckw.transport.service.KwtWaybillOrderV1Service;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

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

/**
 * @author zk
 * @desc 司机app接单Service
 * @date 2023/7/19 0019
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SalesWaybillOrderService {

    private final KwtWaybillOrderSubtaskRepository waybillOrderSubtaskRepository;
    private final KwtWaybillOrderV1Service waybillOrderV1Service;
    private final KwtGatekeeperWaybillOrderRepository gatekeeperWaybillOrderRepository;
    private final KwtLogisticsOrderRepository logisticsOrderRepository;

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

    /**
     * 查询销售数据
     * @param param
     * @return
     */
    public SalesWaybillOrderResp querySalesStatistics(SalesWaybillOrderQueryParam param) {
        log.info("查询销售数据：{}", param);
        SalesWaybillOrderResp salesResp = new SalesWaybillOrderResp();
        //查询销售企业的贸易订单id
        Set<Long> orderIds = tradeOrderInfoService.queryOrderIdByEntId(param.getEntId(), "2");
        if (CollectionUtils.isEmpty(orderIds)) {
            return buildSalesWaybillOrderResp();
        }
        // 查询销售企业的物流订单id
        List<KwtLogisticsOrder> logisticsOrders = logisticsOrderRepository.queryByTradeOrderIds(orderIds);
        if (CollectionUtils.isEmpty(logisticsOrders)) {
            return buildSalesWaybillOrderResp();
        }

        Set<Long> logOrderIds = logisticsOrders.stream()
                .map(KwtLogisticsOrder::getId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());

        // 1. 计算执行中订单（物流订单）
        calOngoingLogOrderCount(param, salesResp);

        // 2.计算今日车次
        calTodayTruckCount(logOrderIds, salesResp);

        // 3.计算场内车辆
        calInsideVehicleCount(logOrderIds, salesResp);

        log.info("查询销售数据成功，结果：{}", salesResp);
        return salesResp;

    }

    /**
     * 构建默认返回数据
     * @return
     */
    private SalesWaybillOrderResp buildSalesWaybillOrderResp() {
        SalesWaybillOrderResp resp = new SalesWaybillOrderResp();
        resp.setOngoingLogOrderCount(0);
        resp.setTodayTruckCount(0);
        resp.setInsideVehicleCount(0);
        resp.setTodayShipmentWeightCount(BigDecimal.ZERO);
        resp.setMonthShipmentWeightCount(BigDecimal.ZERO);

        List<SalesWaybillOrderResp.RecentSevenDayShipmentVO> resultVOs = new ArrayList<>();
        for (int i = 6; i >= 0; i--) {
            LocalDate date = LocalDate.now().minusDays(i);
            String dateStr = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));

            SalesWaybillOrderResp.RecentSevenDayShipmentVO vo = new SalesWaybillOrderResp.RecentSevenDayShipmentVO();
            vo.setDate(dateStr);
            vo.setShipmentWeight(BigDecimal.ZERO);
            resultVOs.add(vo);
        }

        resp.setRecentSevenDayShipmentCountVOs(resultVOs);

        return resp;
    }

    /**
     *  计算执行中订单
     * @param param
     * @param salesResp
     */
    private void calOngoingLogOrderCount(SalesWaybillOrderQueryParam param, SalesWaybillOrderResp salesResp) {
        WaybillOrderReq req = new WaybillOrderReq();
        req.setEntId(String.valueOf(param.getEntId()));
        StatisticsWaybillResp statisticsWaybillResp = waybillOrderV1Service.statisticsWaybillOrder(req);
        if (statisticsWaybillResp == null) {
            salesResp.setOngoingLogOrderCount(Global.NUMERICAL_ZERO);
        }
        List<String> targetStatus = List.of("5", "10", "15");
        List<StatisticsWaybillResp.OrderBillStatusStatistics> orderStatusStatistics = statisticsWaybillResp.getOrderStatusStatistics();
        int ongoingLogOrder = orderStatusStatistics.stream().filter(Objects::nonNull)
                .filter(stat -> targetStatus.contains(stat.getOrderStatus()))
                .mapToInt(s -> {
                    try {
                        return Integer.parseInt(s.getOrderNum());
                    } catch (Exception e) {
                        return 0;
                    }
                })
                .sum();
        salesResp.setOngoingLogOrderCount(ongoingLogOrder);
    }

    /**
     *  计算今日车次
     * @param logOrderIds
     * @param salesResp
     */
    private void calTodayTruckCount(Set<Long> logOrderIds, SalesWaybillOrderResp salesResp) {
        //今日车次/出货量
        todayTruckCount(logOrderIds, salesResp);
        //本月出货量
        monthShipmentWeightCount(logOrderIds, salesResp);
        //近7天出货量
        recentSevenDayShipmentCount(logOrderIds, salesResp);
    }

    /**
     * 今日车次/出货量
     * @param logOrderIds
     * @param salesResp
     */
    private void todayTruckCount(Set<Long> logOrderIds, SalesWaybillOrderResp salesResp) {
        // 今天 00:00:00
        LocalDateTime todayStart = LocalDate.now().atStartOfDay();
        // 今天 23:59:59
        LocalDateTime todayEnd = LocalDate.now().atTime(23, 59, 59);
        List<KwtWaybillOrderSubtask> todayWaybillOrderSub = waybillOrderSubtaskRepository
                .queryWaybillOrderSubByEntIdAndStatus(logOrderIds, CarWaybillV1Enum.COMPLETED.getCode(), todayStart, todayEnd);
        if (CollectionUtils.isEmpty(todayWaybillOrderSub)) {
            salesResp.setTodayTruckCount(Global.NUMERICAL_ZERO);
            salesResp.setTodayShipmentWeightCount(BigDecimal.ZERO);
        }
        //今日车次
        salesResp.setTodayTruckCount(todayWaybillOrderSub.size());
        //今日出货量
        BigDecimal todayLoadAmount = todayWaybillOrderSub.stream()
                .filter(sub -> sub.getLoadAmount() != null)
                .map(KwtWaybillOrderSubtask::getLoadAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        salesResp.setTodayShipmentWeightCount(todayLoadAmount);
    }

    /**
     * 本月出货量
     * @param logOrderIds
     * @param salesResp
     */
    private void monthShipmentWeightCount(Set<Long> logOrderIds, SalesWaybillOrderResp salesResp) {
        // 本月第一天 00:00:00
        LocalDateTime monthStart = LocalDate.now().withDayOfMonth(1).atStartOfDay();
        // 本月最后一天 23:59:59
        LocalDateTime monthEnd = LocalDate.now().withDayOfMonth(LocalDate.now().lengthOfMonth()).atTime(23, 59, 59);
        List<KwtWaybillOrderSubtask> monthWaybillOrderSub = waybillOrderSubtaskRepository
                .queryWaybillOrderSubByEntIdAndStatus(logOrderIds, CarWaybillV1Enum.COMPLETED.getCode(), monthStart, monthEnd);
        if (CollectionUtils.isEmpty(monthWaybillOrderSub)) {
            salesResp.setMonthShipmentWeightCount(BigDecimal.ZERO);
        }
        //本月出货量
        BigDecimal monthLoadAmount = monthWaybillOrderSub.stream()
                .filter(sub -> sub.getLoadAmount() != null)
                .map(KwtWaybillOrderSubtask::getLoadAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        salesResp.setMonthShipmentWeightCount(monthLoadAmount);
    }

    /**
     * 近7天出货量
     * @param logOrderIds
     * @param salesResp
     */
    private void recentSevenDayShipmentCount(Set<Long> logOrderIds, SalesWaybillOrderResp salesResp) {
        // 7天前 00:00:00
        LocalDate today = LocalDate.now();
        LocalDateTime sevenDaysStartTime = today.minusDays(6).atStartOfDay();
        // 今天 23:59:59
        LocalDateTime sevenDaysEndTime = today.atTime(23, 59, 59);

        // 查询数据库,获取近7天的所有已完成子运单数据
        List<KwtWaybillOrderSubtask> sevenDayWaybillOrderSubtask = waybillOrderSubtaskRepository
                .queryWaybillOrderSubByEntIdAndStatus(logOrderIds, CarWaybillV1Enum.COMPLETED.getCode(), sevenDaysStartTime, sevenDaysEndTime);

        // 分组统计,按日期聚合求和
        Map<String, BigDecimal> dailyWeightMap = sevenDayWaybillOrderSubtask.stream()
                .filter(task -> task.getLoadAmount() != null)
                .collect(Collectors.groupingBy(
                        task -> LocalDateTime.ofInstant(task.getCreateTime().toInstant(),
                                java.time.ZoneId.systemDefault()).toLocalDate().toString(),
                        Collectors.mapping(KwtWaybillOrderSubtask::getLoadAmount, Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))
                ));

        // 构建VO列表,按时间顺序，并补全缺失日期
        List<SalesWaybillOrderResp.RecentSevenDayShipmentVO> resultVOs = new ArrayList<>();
        for (int i = 6; i >= 0; i--) {
            // 时间正序排列
            LocalDate date = today.minusDays(i);
            String dateStr = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            BigDecimal weight = dailyWeightMap.getOrDefault(dateStr, BigDecimal.ZERO);

            SalesWaybillOrderResp.RecentSevenDayShipmentVO vo = new SalesWaybillOrderResp.RecentSevenDayShipmentVO();
            vo.setDate(dateStr);
            vo.setShipmentWeight(weight);
            resultVOs.add(vo);
        }
        salesResp.setRecentSevenDayShipmentCountVOs(resultVOs);
    }

    /**
     * 计算场内车辆
     * @param logOrderIds
     * @param salesResp
     */
    private void calInsideVehicleCount(Set<Long> logOrderIds, SalesWaybillOrderResp salesResp) {
        // 查询运单
        List<KwtWaybillOrderSubtask> waybillOrderSubtasks = waybillOrderSubtaskRepository.queryByLogIds(new ArrayList<>(logOrderIds));
        Set<Long> waybillOrderIds = Optional.ofNullable(waybillOrderSubtasks).orElse(Collections.emptyList())
                .stream().map(KwtWaybillOrderSubtask::getWOrderId)
                .collect(Collectors.toSet());
        // 查询门卫
        List<KwtGatekeeperWaybillOrder> kwtGatekeeperWaybillOrders = gatekeeperWaybillOrderRepository
                .queryGatekeeperWaybillOrderByEntId(waybillOrderIds,
                        List.of(GatekeeperStatusEnum.IN_YARD.getCode(),
                                GatekeeperStatusEnum.PENDING_RELEASE.getCode(),
                                GatekeeperStatusEnum.READY_RELEASE.getCode()));
        if (kwtGatekeeperWaybillOrders.isEmpty()) {
            salesResp.setInsideVehicleCount(Global.NUMERICAL_ZERO);
        }
        salesResp.setInsideVehicleCount(kwtGatekeeperWaybillOrders.size());
    }




}
