package com.aircraft.modules.order.service.impl;

import com.aircraft.modules.aircraft.domain.AircraftDevice;
import com.aircraft.modules.aircraft.mapper.AircraftDeviceMapper;
import com.aircraft.modules.order.controller.OrderAnalysisController;
import com.aircraft.modules.order.domain.OrderDetail;
import com.aircraft.modules.order.domain.OrderMain;
import com.aircraft.modules.order.domain.dto.*;
import com.aircraft.modules.order.mapper.OrderDetailMapper;
import com.aircraft.modules.order.mapper.OrderMainMapper;
import com.aircraft.modules.order.service.OrderAnalysisService;
import com.aircraft.modules.route.domain.CpRoute;
import com.aircraft.modules.route.mapper.CpRouteMapper;
import com.aircraft.modules.system.mapper.EmScenicMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Service
public class OrderAnalysisServiceImpl implements OrderAnalysisService {

    @Autowired
    private OrderMainMapper orderMainMapper;
    @Autowired
    private AircraftDeviceMapper aircraftDeviceMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private CpRouteMapper cpRouteMapper;
    @Autowired
    private EmScenicMapper emScenicMapper;
    private static final Logger LOG = LoggerFactory.getLogger(OrderAnalysisController.class);

    // 日期格式化器（用于按日/月/季度/年分组）
    private static final DateTimeFormatter DAY_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private static final DateTimeFormatter MONTH_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM");
    private static final DateTimeFormatter QUARTER_FORMATTER = DateTimeFormatter.ofPattern("yyyy-Qq"); // 如2025-Q1
    private static final DateTimeFormatter YEAR_FORMATTER = DateTimeFormatter.ofPattern("yyyy");

    // 订单状态
    private static final Integer STATUS_NOT_STARTED = 0;//未进行
    private static final Integer STATUS_PROCESSING = 1;//进行中
    private static final Integer STATUS_COMPLETED = 2;//已完成
    private static final Integer STATUS_CANCELED = 3;//已取消


    /**
     * 按日范围分析订单
     */
    @Override
    public OrderAnalysisResult<List<DailyStat>> analyzeByDayRange(LocalDate start, LocalDate end) {
        // 1. 查询时间范围内的所有订单
        List<OrderMain> orders = queryOrdersByDateRange(start, end);
        if (CollectionUtils.isEmpty(orders)) {
            return buildEmptyResult();
        }

        // 2. 按日分组统计每日订单量
        Map<String, Long> dailyCountMap = orders.stream()
                .collect(Collectors.groupingBy(
                        order -> {
                            LocalDate localDate = order.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                            return localDate.format(DAY_FORMATTER); // 按日期字符串分组
                        },
                        Collectors.counting() // 统计每组数量
                ));

        System.out.println(dailyCountMap);

        // 3. 填充每日统计数据（确保日期连续性，即使某天无订单也显示0）
        List<DailyStat> dailyStats = new ArrayList<>();
        LocalDate current = start;
        while (!current.isAfter(end)) {
            String dateStr = current.format(DAY_FORMATTER);
            DailyStat stat = new DailyStat();
            stat.setDate(dateStr);
            stat.setDailyTotalCount(dailyCountMap.getOrDefault(dateStr, 0L));
            dailyStats.add(stat);
            current = current.plusDays(1); // 移至下一天
        }

        // 4. 构建并返回完整结果
        return buildAnalysisResult(orders, dailyStats);
    }


    /**
     * 按月范围分析订单
     */
    @Override
    public OrderAnalysisResult<List<MonthlyStat>> analyzeByMonthRange(LocalDate start, LocalDate end) {
        // 1. 查询时间范围内的所有订单
        List<OrderMain> orders = queryOrdersByDateRange(start, end);
        if (CollectionUtils.isEmpty(orders)) {
            return buildEmptyResult();
        }

        // 2. 按月分组统计每月订单量
        Map<String, Long> monthlyCountMap = orders.stream()
                .collect(Collectors.groupingBy(
                        order -> {
                            LocalDate localDate = order.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                            return localDate.format(MONTH_FORMATTER);
                        },
                        Collectors.counting()
                ));

        // 3. 填充每月统计数据（确保月份连续性）
        List<MonthlyStat> monthlyStats = new ArrayList<>();
        LocalDate current = start.withDayOfMonth(1); // 从当月第一天开始
        LocalDate endMonth = end.withDayOfMonth(1);  // 结束月份第一天

        while (!current.isAfter(endMonth)) {
            String monthStr = current.format(MONTH_FORMATTER);
            MonthlyStat stat = new MonthlyStat();
            stat.setMonth(monthStr);
            stat.setMonthlyTotalCount(monthlyCountMap.getOrDefault(monthStr, 0L));
            monthlyStats.add(stat);
            current = current.plusMonths(1); // 移至下一月
        }

        // 4. 构建并返回完整结果
        return buildAnalysisResult(orders, monthlyStats);
    }


    /**
     * 按季度范围分析订单
     */
    @Override
    public OrderAnalysisResult<List<QuarterlyStat>> analyzeByQuarterRange(LocalDate start, LocalDate end) {
        // 1. 查询时间范围内的所有订单
        List<OrderMain> orders = queryOrdersByDateRange(start, end);
        if (CollectionUtils.isEmpty(orders)) {
            return buildEmptyResult();
        }

        // 2. 按季度分组统计每季度订单量
        Map<String, Long> quarterCountMap = orders.stream()
                .collect(Collectors.groupingBy(
                        order -> {
                            // 将 java.util.Date 转换为 java.time.YearMonth
                            YearMonth yearMonth = YearMonth.from(order.getCreateTime().toInstant().atZone(ZoneId.systemDefault()));
                            int quarter = (yearMonth.getMonthValue() - 1) / 3 + 1;
                            return yearMonth.format(YEAR_FORMATTER) + "-Q" + quarter;
                        },
                        Collectors.counting()
                ));

        // 3. 填充每季度统计数据（确保季度连续性）
        List<QuarterlyStat> quarterlyStats = new ArrayList<>();
        LocalDate currentQuarterStart = start;
        // 调整至当前季度第一天（如2025-05-10 → 2025-04-01）
        currentQuarterStart = currentQuarterStart.minusMonths((currentQuarterStart.getMonthValue() - 1) % 3);
        currentQuarterStart = currentQuarterStart.withDayOfMonth(1);

        while (!currentQuarterStart.isAfter(end)) {
            // 计算当前季度标识（如2025-Q2）
            int quarter = (currentQuarterStart.getMonthValue() - 1) / 3 + 1;
            String quarterStr = currentQuarterStart.format(YEAR_FORMATTER) + "-Q" + quarter;

            QuarterlyStat stat = new QuarterlyStat();
            stat.setQuarter(quarterStr);
            stat.setQuarterlyTotalCount(quarterCountMap.getOrDefault(quarterStr, 0L));
            quarterlyStats.add(stat);

            // 移至下一季度第一天
            currentQuarterStart = currentQuarterStart.plusMonths(3);
        }

        // 4. 构建并返回完整结果
        return buildAnalysisResult(orders, quarterlyStats);
    }


    /**
     * 按年范围分析订单
     */
    @Override
    public OrderAnalysisResult<List<YearlyStat>> analyzeByYearRange(LocalDate start, LocalDate end) {
        // 1. 查询时间范围内的所有订单
        List<OrderMain> orders = queryOrdersByDateRange(start, end);
        if (CollectionUtils.isEmpty(orders)) {
            return buildEmptyResult();
        }

        // 2. 按年分组统计每年订单量
        Map<String, Long> yearCountMap = orders.stream()
                .collect(Collectors.groupingBy(
                        order -> {
                            LocalDate localDate = order.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                            return localDate.format(YEAR_FORMATTER);
                        },
                        Collectors.counting()
                ));
        // 3. 填充每年统计数据（确保年份连续性）
        List<YearlyStat> yearlyStats = new ArrayList<>();
        int startYear = start.getYear();
        int endYear = end.getYear();

        for (int year = startYear; year <= endYear; year++) {
            String yearStr = String.valueOf(year);
            YearlyStat stat = new YearlyStat();
            stat.setYear(yearStr);
            stat.setYearlyTotalCount(yearCountMap.getOrDefault(yearStr, 0L));
            yearlyStats.add(stat);
        }

        // 4. 构建并返回完整结果
        return buildAnalysisResult(orders, yearlyStats);
    }

    @Override
    public <T> OrderAnalysisResult<T> analyzeAllOrders(List<OrderMain> allOrders) {
        return buildAnalysisOrdersResult(allOrders);
    }


// ====================== 通用工具方法 ======================

    /**
     * 根据日期范围查询订单
     */
    private List<OrderMain> queryOrdersByDateRange(LocalDate start, LocalDate end) {
        // MyBatis Plus 条件构造器：查询 create_time 在 [start, end] 范围内的订单
        LambdaQueryWrapper<OrderMain> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ge(OrderMain::getCreateTime, start.atStartOfDay()) // 开始时间：当天00:00:00
                .le(OrderMain::getCreateTime, end.atTime(23, 59, 59)); // 结束时间：当天23:59:59
        return orderMainMapper.selectList(queryWrapper);
    }

    /**
     * 构建完整的订单分析结果
     */
    private <T> OrderAnalysisResult<T> buildAnalysisResult(List<OrderMain> orders, T timeSeriesData) {
        OrderAnalysisResult<T> result = buildAnalysisOrdersResult(orders);
        // 6. 时间序列数据（日/月/季/年统计）
        result.setTimeSeriesData(timeSeriesData);
        return result;
    }

    //处理订单返回结果
    private <T> OrderAnalysisResult<T> buildAnalysisOrdersResult(List<OrderMain> orders) {
        OrderAnalysisResult<T> result = new OrderAnalysisResult<>();

        // 1. 基础统计指标
        result.setTotalOrderCount((long) orders.size()); // 总订单量
        result.setTotalOrderAmount(calculateTotalAmount(orders)); // 总金额

        // 2. 状态统计
        long notStartCount = countOrdersByStatus(orders, STATUS_NOT_STARTED);
        long progressingCount = countOrdersByStatus(orders, STATUS_PROCESSING);
        long completedCount = countOrdersByStatus(orders, STATUS_COMPLETED);
        long canceledCount = countOrdersByStatus(orders, STATUS_CANCELED);
        result.setNoStartOrderCount(notStartCount);
        result.setInProgressOrderCount(progressingCount);
        result.setCompletedOrderCount(completedCount);
        result.setCancelOrderCount(canceledCount);
        // 计算完成率（避免除0）
        result.setCompletionRate(orders.isEmpty() ? 0D : (completedCount * 100.0) / orders.size());

        // 3. 分页信息和订单列表（默认取第一页，每页10条，实际可根据前端参数调整）
        Page<OrderMain> page = new Page<>(1, 10);
        result.setPageInfo(buildPageInfo(page, orders.size()));
        // 截取分页数据（实际应在SQL层分页，此处简化）
        List<OrderMain> pageOrders = orders.stream()
                .skip((page.getCurrent() - 1) * page.getSize())
                .limit(page.getSize())
                .collect(Collectors.toList());
        result.setOrderList(pageOrders);

        // 4. 无人机型号占比
        result.setDroneModelDistribution(calculateDroneModelDistribution(orders));

        // 5. 景区路线订单分布
        result.setRouteDistribution(calculateRouteDistribution(orders));
        return result;
    }

    /**
     * 计算订单总金额
     */
    private BigDecimal calculateTotalAmount(List<OrderMain> orders) {
        return orders.stream()
                .map(OrderMain::getTotalAmount) // totalAmount为订单总金额
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    /**
     * 按状态统计订单数量
     */
    private long countOrdersByStatus(List<OrderMain> orders, Integer mainOrderStatus) {
        if (orders == null) return 0;

        // 遍历订单主表，统计主单的状态数量
        return orders.stream()
                .filter(order -> mainOrderStatus.equals(order.getMainOrderStatus()))
                .count();
    }

    /**
     * 计算无人机型号订单占比
     */
    private Map<String, Double> calculateDroneModelDistribution(List<OrderMain> orders) {
        if (orders == null || orders.isEmpty()) {
            return Collections.emptyMap();
        }

        // 根据订单id，找到对应的订单详情（OrderDetail）数据
        List<OrderDetail> orderDetails = fetchOrderDetailsByOrderIds(
                orders.stream()
                        .map(OrderMain::getId)
                        .filter(Objects::nonNull)
                        .collect(Collectors.toList())
        );

        if (orderDetails.isEmpty()) {
            return Collections.emptyMap();
        }

        // 从订单详情中提取所有飞行设备 ID（去重处理）
        List<Long> deviceIds = orderDetails.stream()
                .map(OrderDetail::getDeviceId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());

        // 获取飞行设备 ID 对应的 AircraftDevice 对象的映射
        List<AircraftDevice> deviceList = aircraftDeviceMapper.getAircraftDeviceById(deviceIds);
        Map<Long, AircraftDevice> deviceMap = deviceList.stream()
                .collect(Collectors.toMap(
                        AircraftDevice::getId,  // 提取 ID 作为 key
                        device -> device,       // 设备对象作为 value
                        (existing, replacement) -> existing  // 处理 ID 重复（保留第一个）
                ));

        // 按型号分组统计数量（处理设备不存在的情况）
        Map<String, Long> modelCountMap = orderDetails.stream()
                .filter(detail -> detail.getDeviceId() != null && deviceMap != null && deviceMap.containsKey(detail.getDeviceId()))
                .map(detail -> deviceMap.get(detail.getDeviceId()).getModel())
                .filter(Objects::nonNull)
                .collect(Collectors.groupingBy(model -> model, Collectors.counting()));

        // 转换为占比（百分比），基于有效订单详情数量计算
        Map<String, Double> distribution = new HashMap<>();
        long validDetailCount = modelCountMap.values().stream().mapToLong(Long::longValue).sum();

        if (validDetailCount > 0) {
            modelCountMap.forEach((model, count) -> {
                double percentage = (count * 100.0) / validDetailCount;
                distribution.put(model, Math.round(percentage * 100.0) / 100.0); // 保留两位小数
            });
        }

        return distribution;
    }

    // 通过订单ID获取订单详情的方法
    @Transactional(readOnly = true)
    public List<OrderDetail> fetchOrderDetailsByOrderIds(List<Long> orderIds) {
        // 参数校验
        if (orderIds == null || orderIds.isEmpty()) {
            throw new IllegalArgumentException("订单ID列表不能为空");
        }

        // 分批查询（每批1000个ID，防止SQL IN子句过长）
        final int BATCH_SIZE = 1000;
        List<OrderDetail> result = new ArrayList<>();

        for (List<Long> batchIds : partitionList(orderIds, BATCH_SIZE)) {
            List<OrderDetail> batchResult = orderDetailMapper.getOrderDetailsByOrderIds(batchIds);
            if (batchResult != null) {
                result.addAll(batchResult);
            }
        }

        return result;
    }

    /**
     * 将列表按指定大小分割为多个子列表
     *
     * @param list      原始列表
     * @param batchSize 每个子列表的最大大小
     * @return 子列表集合
     */
    private <T> List<List<T>> partitionList(List<T> list, int batchSize) {
        if (list == null || list.isEmpty()) {
            return Collections.emptyList();
        }

        return IntStream.range(0, (list.size() + batchSize - 1) / batchSize)
                .mapToObj(i -> list.subList(i * batchSize, Math.min((i + 1) * batchSize, list.size())))
                .collect(Collectors.toList());
    }

    /**
     * 计算景区内各路线的订单分布
     */
    public List<RouteStat> calculateRouteDistribution(List<OrderMain> orders) {
        // 统计各路线的订单数量
        Map<Long, Long> routeCountMap = new HashMap<>();
        for (OrderMain order : Optional.ofNullable(orders).orElse(Collections.emptyList())) {
            if (order == null || order.getRouteIds() == null || order.getRouteIds().isEmpty()) {
                continue;
            }

            String[] routeIdArray = order.getRouteIds().split(",");
            for (String routeIdStr : routeIdArray) {
                String trimmedRouteId = routeIdStr.trim();
                if (!trimmedRouteId.isEmpty()) {
                    try {
                        Long routeId = Long.parseLong(trimmedRouteId);
                        routeCountMap.put(routeId, routeCountMap.getOrDefault(routeId, 0L) + 1);
                    } catch (NumberFormatException e) {
                        LOG.error("路线id格式错误: {}", trimmedRouteId, e);
                    }
                }
            }
        }

        // 转换统计结果为RouteStat列表
        List<RouteStat> routeDistribution = new ArrayList<>();

        if (!routeCountMap.isEmpty()) {
            // 提取所有路线ID
            Set<Long> routeIds = routeCountMap.keySet();

            // 批量查询所有路线信息（仅需查询路线名称和景区ID）
            List<CpRoute> routes = cpRouteMapper.listRoutesByIds(new ArrayList<>(routeIds));
            Map<Long, CpRoute> routeMap = routes.stream()
                    .collect(Collectors.toMap(CpRoute::getId, route -> route));

            // 提取所有景区ID
            Set<Long> scenicIds = routes.stream()
                    .map(CpRoute::getScenicId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());

            // 批量查询所有景区名称确保不为空
//            Map<Long, String> scenicNameMap = emScenicMapper.getScenicNameMap(new ArrayList<>(scenicIds));
            Map<Long, String> scenicNameMap = Collections.emptyMap();
            if (!scenicIds.isEmpty()) {
                scenicNameMap = emScenicMapper.getScenicNameMap(new ArrayList<>(scenicIds));
            }

            // 组装结果
            for (Map.Entry<Long, Long> entry : routeCountMap.entrySet()) {
                Long routeId = entry.getKey();
                Long count = entry.getValue();

                RouteStat stat = new RouteStat();
                stat.setRouteId(routeId);
                stat.setCount(count);

                CpRoute route = routeMap.get(routeId);
                if (route != null) {
                    stat.setRouteName(route.getName());

                    Long scenicId = route.getScenicId();
                    if (scenicId != null) {
                        stat.setScenicName(scenicNameMap.getOrDefault(scenicId, "未知景区"));
                    } else {
                        stat.setScenicName("未知景区");
                    }
                } else {
                    stat.setRouteName("未知路线");
                    stat.setScenicName("未知景区");
                }

                routeDistribution.add(stat);
            }
        }

        return routeDistribution;
    }
    /**
     * 计算区域订单分布
     */
//    private Map<String, Long> calculateRegionDistribution(List<OrderMain> orders) {
//        if (orders == null || orders.isEmpty()) {
//            return Collections.emptyMap();
//        }
//
//        // 提取所有订单中的区域ID（去重）
//        List<Long> regionIds = orders.stream()
//                .map(OrderMain::getAttractionId) // 获取区域id
//                .filter(Objects::nonNull)
//                .distinct()
//                .collect(Collectors.toList());
//
//        // 通过区域ID查询区域名称映射
//        Map<Long, String> regionNameMap = emAreaService.getNameMapByIds(regionIds);
//
//        // 按区域名称分组统计订单数量
//        return orders.stream()
//                .filter(order -> order.getAttractionId() != null && regionNameMap.containsKey(order.getAttractionId()))
//                .collect(Collectors.groupingBy(
//                        order -> regionNameMap.get(order.getAttractionId()), // 使用景区区域名称作为分组键
//                        Collectors.counting()
//                ));
//    }

    /**
     * 构建分页信息
     */
    private PageInfo buildPageInfo(Page<?> page, int total) {
        PageInfo pageInfo = new PageInfo();
        pageInfo.setPageNum((int) page.getCurrent());
        pageInfo.setPageSize((int) page.getSize());
        pageInfo.setTotal((long) total);
        return pageInfo;
    }

    /**
     * 构建空结果（无订单时）
     */
    private <T> OrderAnalysisResult<T> buildEmptyResult() {
        OrderAnalysisResult<T> result = new OrderAnalysisResult<>();
        result.setTotalOrderCount(0L);
        result.setTotalOrderAmount(BigDecimal.ZERO);
        result.setInProgressOrderCount(0L);
        result.setCompletedOrderCount(0L);
        result.setCompletionRate(0D);
        result.setPageInfo(new PageInfo());
        result.setOrderList(Collections.emptyList());
        result.setDroneModelDistribution(Collections.emptyMap());
        result.setRouteDistribution(Collections.emptyList());
        result.setTimeSeriesData(null);
        return result;
    }
}