package com.example.demo.service;

import com.example.demo.model.Order;
import com.example.demo.model.OrderStatus;
import com.example.demo.model.PaymentStatus;
import com.example.demo.repository.OrderRepository;
import com.example.demo.repository.PaymentRepository;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

@Service
public class DashboardService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private OrderRepository orderRepository;

    @Autowired
    private PaymentRepository paymentRepository;

    /**
     * 获取仪表盘概览数据
     */
    public Map<String, Object> getDashboardOverview() {
        Map<String, Object> overview = new HashMap<>();

        // 用户总数
        long totalUsers = userRepository.count();
        overview.put("totalUsers", totalUsers);

        // 付费用户数（有成功支付记录的不同用户数）- 优化：直接在数据库层面统计
        long paidUsers = paymentRepository.countDistinctUsersByStatus(PaymentStatus.SUCCESS);
        overview.put("paidUsers", paidUsers);

        // 今日收入（今日成功支付的金额）- 优化：直接在数据库层面求和
        LocalDateTime todayStart = LocalDate.now().atStartOfDay();
        LocalDateTime todayEnd = LocalDate.now().atTime(23, 59, 59);
        
        BigDecimal todayRevenue = paymentRepository.sumAmountByStatusAndPaidAtBetween(
                PaymentStatus.SUCCESS, todayStart, todayEnd);
        overview.put("todayRevenue", todayRevenue != null ? todayRevenue : BigDecimal.ZERO);

        // 当月转化率（当月付费用户数 / 当月新增用户数）
        LocalDateTime currentMonthStart = LocalDate.now().withDayOfMonth(1).atStartOfDay();
        LocalDateTime currentMonthEnd = currentMonthStart.plusMonths(1).minusSeconds(1);
        long monthNewUsers = userRepository.countByCreatedAtBetween(currentMonthStart, currentMonthEnd);
        long monthPaidUsers = paymentRepository.countDistinctUsersByStatusAndPaidAtBetween(
                PaymentStatus.SUCCESS, currentMonthStart, currentMonthEnd);
        double conversionRate = monthNewUsers > 0 ? (double) monthPaidUsers / monthNewUsers * 100 : 0;
        overview.put("conversionRate", Math.round(conversionRate * 100.0) / 100.0);

        // 今日新增用户 - 优化：直接在数据库层面统计
        long todayNewUsers = userRepository.countByCreatedAtBetween(todayStart, todayEnd);
        overview.put("todayNewUsers", todayNewUsers);

        // ===== 计算环比变化（当前值 vs 上月底值）=====
        LocalDate today = LocalDate.now();
        
        // 上月底时间点
        LocalDate lastMonthEnd = today.withDayOfMonth(1).minusDays(1);
        LocalDateTime lastMonthEndTime = lastMonthEnd.atTime(23, 59, 59);

        // 用户总数环比：当前总用户数 vs 上月底总用户数
        long lastMonthTotalUsers = userRepository.countByCreatedAtBefore(lastMonthEndTime.plusSeconds(1));
        double totalUsersChange = lastMonthTotalUsers > 0 ? 
                ((double) totalUsers - lastMonthTotalUsers) / lastMonthTotalUsers * 100 : 
                (totalUsers > 0 ? 100 : 0);
        overview.put("totalUsersChange", Math.round(totalUsersChange * 10.0) / 10.0);

        // 付费用户环比：当前付费用户数 vs 上月底付费用户数
        long lastMonthPaidUsers = paymentRepository.countDistinctUsersByStatusAndPaidAtBefore(
                PaymentStatus.SUCCESS, lastMonthEndTime.plusSeconds(1));
        double paidUsersChange = lastMonthPaidUsers > 0 ? 
                ((double) paidUsers - lastMonthPaidUsers) / lastMonthPaidUsers * 100 : 
                (paidUsers > 0 ? 100 : 0);
        overview.put("paidUsersChange", Math.round(paidUsersChange * 10.0) / 10.0);

        // 昨日收入（用于对比今日收入）
        LocalDateTime yesterdayStart = today.minusDays(1).atStartOfDay();
        LocalDateTime yesterdayEnd = today.minusDays(1).atTime(23, 59, 59);
        BigDecimal yesterdayRevenue = paymentRepository.sumAmountByStatusAndPaidAtBetween(
                PaymentStatus.SUCCESS, yesterdayStart, yesterdayEnd);
        if (yesterdayRevenue == null) yesterdayRevenue = BigDecimal.ZERO;
        BigDecimal todayRevenueValue = todayRevenue != null ? todayRevenue : BigDecimal.ZERO;
        
        // 收入变化率
        double todayRevenueChange = yesterdayRevenue.compareTo(BigDecimal.ZERO) > 0 ?
                todayRevenueValue.subtract(yesterdayRevenue)
                        .divide(yesterdayRevenue, 4, java.math.RoundingMode.HALF_UP)
                        .multiply(BigDecimal.valueOf(100)).doubleValue() :
                (todayRevenueValue.compareTo(BigDecimal.ZERO) > 0 ? 100 : 0);
        overview.put("todayRevenueChange", Math.round(todayRevenueChange * 10.0) / 10.0);

        return overview;
    }

    /**
     * 获取日活数据（最近30天）
     */
    public Map<String, Object> getDailyActiveUsers() {
        Map<String, Object> result = new HashMap<>();
        
        List<Map<String, Object>> dailyData = new ArrayList<>();
        LocalDate endDate = LocalDate.now();
        
        for (int i = 29; i >= 0; i--) {
            LocalDate date = endDate.minusDays(i);
            LocalDateTime startOfDay = date.atStartOfDay();
            LocalDateTime endOfDay = date.atTime(23, 59, 59);
            
            // 统计当天有订单的用户数作为日活 - 优化：直接在数据库层面统计
            long dailyActiveUsers = orderRepository.countDistinctUsersByCreatedAtBetween(startOfDay, endOfDay);
            
            Map<String, Object> dayData = new HashMap<>();
            dayData.put("date", date.format(DateTimeFormatter.ofPattern("MM-dd")));
            dayData.put("activeUsers", dailyActiveUsers);
            dailyData.add(dayData);
        }
        
        result.put("dailyData", dailyData);
        return result;
    }

    /**
     * 获取收入趋势数据（最近30天）
     */
    public Map<String, Object> getRevenueTrend() {
        Map<String, Object> result = new HashMap<>();
        
        List<Map<String, Object>> revenueData = new ArrayList<>();
        LocalDate endDate = LocalDate.now();
        
        for (int i = 29; i >= 0; i--) {
            LocalDate date = endDate.minusDays(i);
            LocalDateTime startOfDay = date.atStartOfDay();
            LocalDateTime endOfDay = date.atTime(23, 59, 59);
            
            // 统计当天成功支付的金额 - 优化：直接在数据库层面求和
            BigDecimal dailyRevenue = paymentRepository.sumAmountByStatusAndPaidAtBetween(
                    PaymentStatus.SUCCESS, startOfDay, endOfDay);
            
            Map<String, Object> dayData = new HashMap<>();
            dayData.put("date", date.format(DateTimeFormatter.ofPattern("MM-dd")));
            dayData.put("revenue", dailyRevenue);
            revenueData.add(dayData);
        }
        
        result.put("revenueData", revenueData);
        return result;
    }

    /**
     * 获取订单状态分布
     */
    public Map<String, Object> getOrderStatusDistribution() {
        Map<String, Object> result = new HashMap<>();
        
        List<Map<String, Object>> statusData = new ArrayList<>();
        for (OrderStatus status : OrderStatus.values()) {
            long count = orderRepository.countByStatus(status);
            Map<String, Object> statusInfo = new HashMap<>();
            statusInfo.put("status", status.name());
            statusInfo.put("count", count);
            statusData.add(statusInfo);
        }
        
        result.put("statusData", statusData);
        return result;
    }

    /**
     * 获取支付方式分布
     */
    public Map<String, Object> getPaymentMethodDistribution() {
        Map<String, Object> result = new HashMap<>();
        
        List<Map<String, Object>> methodData = new ArrayList<>();
        // 这里需要根据PaymentMethod枚举来统计，暂时简化处理
        Map<String, Long> methodCounts = new HashMap<>();
        
        paymentRepository.findAll().forEach(payment -> {
            String method = payment.getPaymentMethod().name();
            methodCounts.put(method, methodCounts.getOrDefault(method, 0L) + 1);
        });
        
        methodCounts.forEach((method, count) -> {
            Map<String, Object> methodInfo = new HashMap<>();
            methodInfo.put("method", method);
            methodInfo.put("count", count);
            methodData.add(methodInfo);
        });
        
        result.put("methodData", methodData);
        return result;
    }

    /**
     * 获取最近订单列表
     */
    public Map<String, Object> getRecentOrders() {
        Map<String, Object> result = new HashMap<>();
        
        List<Order> recentOrders = orderRepository.findAll().stream()
                .sorted((o1, o2) -> o2.getCreatedAt().compareTo(o1.getCreatedAt()))
                .limit(10)
                .toList();
        
        List<Map<String, Object>> orderList = new ArrayList<>();
        recentOrders.forEach(order -> {
            Map<String, Object> orderInfo = new HashMap<>();
            orderInfo.put("id", order.getId());
            orderInfo.put("orderNumber", order.getOrderNumber());
            orderInfo.put("totalAmount", order.getTotalAmount());
            orderInfo.put("status", order.getStatus().name());
            orderInfo.put("createdAt", order.getCreatedAt());
            orderInfo.put("username", order.getUser().getUsername());
            orderList.add(orderInfo);
        });
        
        result.put("orders", orderList);
        return result;
    }
}
