package com.erp.tenant.service.report.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.erp.tenant.dto.report.ReportPageResponse;
import com.erp.tenant.repository.order.OrderRepository;
import com.erp.tenant.repository.stock.StockRepository;
import com.erp.tenant.service.report.ReportService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import com.erp.common.core.model.PageResponse;

/**
 * 租户端报表统计服务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ReportServiceImpl implements ReportService {

    private final OrderRepository orderRepository;
    private final StockRepository stockRepository;

    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    // ==================== 订单报表 ====================

    @Override
    public IPage<Map<String, Object>> getOrderReport(Long tenantId, String platform, Long shopId,
                                                      String startDate, String endDate,
                                                      String groupBy, String trend,
                                                      int page, int pageSize) {
        // 按平台分组
        List<OrderRepository.OrderPlatformStats> stats =
                orderRepository.statsByPlatform(tenantId, startDate, endDate);

        List<Map<String, Object>> result = stats.stream()
                .map(s -> {
                    Map<String, Object> m = new LinkedHashMap<>();
                    m.put("platform", s.platform);
                    m.put("orderCount", s.orderCount);
                    m.put("totalAmount", s.totalAmount);
                    m.put("goodsAmount", s.goodsAmount);
                    m.put("freight", s.freight);
                    m.put("completedCount", s.completedCount);
                    m.put("cancelledCount", s.cancelledCount);
                    return m;
                })
                .collect(Collectors.toList());

        // Manual pagination
        int total = result.size();
        int from = (page - 1) * pageSize;
        int to = Math.min(from + pageSize, total);
        List<Map<String, Object>> pageData = from < total ? result.subList(from, to) : Collections.emptyList();

        Page<Map<String, Object>> resultPage = new Page<>(page, pageSize);
        resultPage.setTotal(total);
        resultPage.setRecords(pageData);
        return resultPage;
    }

    // ==================== 销售报表 ====================

    @Override
    public ReportPageResponse.SalesReportDTO getSalesSummary(Long tenantId, String platform, Long shopId,
                                                              String startDate, String endDate, String period) {
        String dateFormat = "day".equals(period) ? "%Y-%m-%d" : "%Y-%m";
        List<OrderRepository.OrderSalesStats> stats =
                orderRepository.statsByPeriod(tenantId, startDate, endDate, dateFormat);

        long totalOrders = 0;
        BigDecimal totalSales = BigDecimal.ZERO;
        BigDecimal totalAvg = BigDecimal.ZERO;
        long totalCompleted = 0;
        int count = 0;

        for (OrderRepository.OrderSalesStats s : stats) {
            totalOrders += (s.orderCount != null ? s.orderCount : 0);
            if (s.salesAmount != null) totalSales = totalSales.add(s.salesAmount);
            if (s.avgOrderAmount != null) totalAvg = totalAvg.add(s.avgOrderAmount);
            totalCompleted += (s.completedCount != null ? s.completedCount : 0);
            count++;
        }

        return ReportPageResponse.SalesReportDTO.builder()
                .orderCount(totalOrders)
                .salesAmount(totalSales)
                .avgOrderAmount(count > 0 ? totalAvg.divide(BigDecimal.valueOf(count), 2, RoundingMode.HALF_UP) : BigDecimal.ZERO)
                .completedCount(totalCompleted)
                .build();
    }

    @Override
    public IPage<Map<String, Object>> getSalesReport(Long tenantId, String platform, Long shopId,
                                                       String startDate, String endDate,
                                                       String period, String trend,
                                                       int page, int pageSize) {
        String dateFormat = "day".equals(period) ? "%Y-%m-%d" : "week".equals(period) ? "%x-W%v" : "%Y-%m";
        List<OrderRepository.OrderSalesStats> stats =
                orderRepository.statsByPeriod(tenantId, startDate, endDate, dateFormat);

        List<Map<String, Object>> result = stats.stream()
                .map(s -> {
                    Map<String, Object> m = new LinkedHashMap<>();
                    m.put("period", s.period);
                    m.put("orderCount", s.orderCount);
                    m.put("salesAmount", s.salesAmount);
                    m.put("goodsAmount", s.goodsAmount);
                    m.put("avgOrderAmount", s.avgOrderAmount);
                    m.put("completedCount", s.completedCount);
                    return m;
                })
                .collect(Collectors.toList());

        int total = result.size();
        int from = (page - 1) * pageSize;
        int to = Math.min(from + pageSize, total);
        List<Map<String, Object>> pageData = from < total ? result.subList(from, to) : Collections.emptyList();

        Page<Map<String, Object>> resultPage = new Page<>(page, pageSize);
        resultPage.setTotal(total);
        resultPage.setRecords(pageData);
        return resultPage;
    }

    // ==================== 库存报表 ====================

    @Override
    public ReportPageResponse.StockReportDTO getStockOverview(Long tenantId, Long warehouseId, Integer slowDays) {
        Long totalStocks = stockRepository.countByWarehouse(tenantId, warehouseId);
        Integer totalQuantity = stockRepository.sumQuantityByTenant(tenantId, warehouseId);
        Long lowStock = stockRepository.countLowStock(tenantId, warehouseId);
        Long outOfStock = stockRepository.countOutOfStock(tenantId, warehouseId);

        return ReportPageResponse.StockReportDTO.builder()
                .totalStocks(totalStocks != null ? totalStocks : 0L)
                .totalQuantity(totalQuantity != null ? totalQuantity : 0)
                .totalAvailable(totalQuantity != null ? totalQuantity : 0)
                .lowStockCount(lowStock != null ? lowStock : 0L)
                .outOfStockCount(outOfStock != null ? outOfStock : 0L)
                .slowMovingCount(0L)
                .build();
    }

    @Override
    public IPage<Map<String, Object>> getSlowMovingReport(Long tenantId, Long warehouseId,
                                                            Integer slowDays, int page, int pageSize) {
        // TODO: implement slow moving report
        Page<Map<String, Object>> resultPage = new Page<>(page, pageSize);
        resultPage.setTotal(0);
        resultPage.setRecords(Collections.emptyList());
        return resultPage;
    }

    @Override
    public IPage<Map<String, Object>> getTurnoverReport(Long tenantId, Long warehouseId,
                                                          int page, int pageSize) {
        // TODO: implement turnover report
        Page<Map<String, Object>> resultPage = new Page<>(page, pageSize);
        resultPage.setTotal(0);
        resultPage.setRecords(Collections.emptyList());
        return resultPage;
    }

    // ==================== API调用统计 ====================

    @Override
    public IPage<Map<String, Object>> getApiUsageReport(Long tenantId, String platform,
                                                         String startDate, String endDate,
                                                         String period, String trend,
                                                         int page, int pageSize) {
        // TODO: implement API usage report using pull_records table
        Page<Map<String, Object>> resultPage = new Page<>(page, pageSize);
        resultPage.setTotal(0);
        resultPage.setRecords(Collections.emptyList());
        return resultPage;
    }
}
