using AdsManagerService.Infrastructure;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace AdsManagerService.API.Controllers;

/// <summary>
/// EN: Handler for getting top advertisers by spend.
/// VI: Handler lấy top advertisers theo chi tiêu.
/// </summary>
public class GetTopAdvertisersQueryHandler : IRequestHandler<GetTopAdvertisersQuery, List<TopAdvertiserDto>>
{
    private readonly AdsManagerServiceContext _context;

    public GetTopAdvertisersQueryHandler(AdsManagerServiceContext context)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
    }

    public async Task<List<TopAdvertiserDto>> Handle(GetTopAdvertisersQuery request, CancellationToken cancellationToken)
    {
        var topAdvertisers = await _context.Campaigns
            .GroupBy(c => c.AdvertiserId)
            .Select(g => new TopAdvertiserDto
            {
                AdvertiserId = g.Key,
                TotalCampaigns = g.Count(),
                TotalSpend = g.Sum(c => c.TotalSpend),
                ActiveCampaigns = g.Count(c => c.Status.Name == "Active")
            })
            .OrderByDescending(a => a.TotalSpend)
            .Take(request.Limit)
            .ToListAsync(cancellationToken);

        return topAdvertisers;
    }
}

/// <summary>
/// EN: Handler for getting revenue analytics.
/// VI: Handler lấy phân tích doanh thu.
/// </summary>
public class GetRevenueAnalyticsQueryHandler : IRequestHandler<GetRevenueAnalyticsQuery, RevenueAnalyticsDto>
{
    private readonly AdsManagerServiceContext _context;

    public GetRevenueAnalyticsQueryHandler(AdsManagerServiceContext context)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
    }

    public async Task<RevenueAnalyticsDto> Handle(GetRevenueAnalyticsQuery request, CancellationToken cancellationToken)
    {
        var query = _context.Campaigns.AsQueryable();

        // EN: Filter by date range if provided
        // VI: Lọc theo khoảng thời gian nếu có
        if (request.StartDate.HasValue)
            query = query.Where(c => c.CreatedAt >= request.StartDate.Value);

        if (request.EndDate.HasValue)
            query = query.Where(c => c.CreatedAt <= request.EndDate.Value);

        var campaigns = await query.ToListAsync(cancellationToken);

        var totalRevenue = campaigns.Sum(c => c.TotalSpend);
        var totalCampaigns = campaigns.Count;

        // EN: Group revenue by objective
        // VI: Nhóm doanh thu theo mục tiêu
        var revenueByObjective = campaigns
            .GroupBy(c => c.Objective.Name)
            .ToDictionary(
                g => g.Key,
                g => g.Sum(c => c.TotalSpend)
            );

        return new RevenueAnalyticsDto
        {
            TotalRevenue = totalRevenue,
            AverageRevenuePerCampaign = totalCampaigns > 0 ? totalRevenue / totalCampaigns : 0,
            TotalCampaigns = totalCampaigns,
            RevenueByObjective = revenueByObjective
        };
    }
}
