using MediatR;
using TakeoutSaaS.Application.App.Statistics.Dto;
using TakeoutSaaS.Application.App.Statistics.Queries;
using TakeoutSaaS.Domain.Tenants.Repositories;

namespace TakeoutSaaS.Application.App.Statistics.Handlers;

/// <summary>
/// 获取收入统计处理器。
/// </summary>
public sealed class GetRevenueStatisticsQueryHandler(IStatisticsRepository statisticsRepository)
    : IRequestHandler<GetRevenueStatisticsQuery, RevenueStatisticsDto>
{
    /// <inheritdoc />
    public async Task<RevenueStatisticsDto> Handle(GetRevenueStatisticsQuery request, CancellationToken cancellationToken)
    {
        var now = DateTime.UtcNow;
        var currentMonth = new DateTime(now.Year, now.Month, 1);
        var currentQuarter = GetQuarterStart(now);
        var startMonth = currentMonth.AddMonths(-request.MonthsCount + 1);

        // 查询所有已付款的账单
        var bills = await statisticsRepository.GetPaidBillsAsync(cancellationToken);

        // 总收入
        var totalRevenue = bills.Sum(b => b.AmountPaid);

        // 本月收入
        var monthlyRevenue = bills
            .Where(b => b.PeriodStart >= currentMonth)
            .Sum(b => b.AmountPaid);

        // 本季度收入
        var quarterlyRevenue = bills
            .Where(b => b.PeriodStart >= currentQuarter)
            .Sum(b => b.AmountPaid);

        // 月度收入明细
        var monthlyDetails = bills
            .Where(b => b.PeriodStart >= startMonth)
            .GroupBy(b => new { b.PeriodStart.Year, b.PeriodStart.Month })
            .Select(g => new MonthlyRevenueItem
            {
                Year = g.Key.Year,
                Month = g.Key.Month,
                Amount = g.Sum(b => b.AmountPaid),
                BillCount = g.Count()
            })
            .OrderBy(m => m.Year)
            .ThenBy(m => m.Month)
            .ToList();

        return new RevenueStatisticsDto
        {
            TotalRevenue = totalRevenue,
            MonthlyRevenue = monthlyRevenue,
            QuarterlyRevenue = quarterlyRevenue,
            MonthlyDetails = monthlyDetails
        };
    }

    /// <summary>
    /// 获取季度开始时间。
    /// </summary>
    private static DateTime GetQuarterStart(DateTime date)
    {
        var quarter = (date.Month - 1) / 3;
        var quarterStartMonth = quarter * 3 + 1;
        return new DateTime(date.Year, quarterStartMonth, 1);
    }
}
