using MediatR;
using Microsoft.EntityFrameworkCore;
using AdsAnalyticsService.Infrastructure;

namespace AdsAnalyticsService.API.Application.Queries;

/// <summary>
/// EN: Handler for GetCampaignMetricsQuery.
/// VI: Handler cho GetCampaignMetricsQuery.
/// </summary>
public class GetCampaignMetricsQueryHandler : IRequestHandler<GetCampaignMetricsQuery, CampaignMetricsDto?>
{
    private readonly AdsAnalyticsServiceContext _context;
    private readonly ILogger<GetCampaignMetricsQueryHandler> _logger;

    public GetCampaignMetricsQueryHandler(
        AdsAnalyticsServiceContext context,
        ILogger<GetCampaignMetricsQueryHandler> logger)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public async Task<CampaignMetricsDto?> Handle(GetCampaignMetricsQuery request, CancellationToken cancellationToken)
    {
        // EN: Aggregate metrics for the campaign within date range
        // VI: Tổng hợp metrics cho chiến dịch trong khoảng thời gian
        var metrics = await _context.CampaignMetrics
            .Where(m => m.CampaignId == request.CampaignId
                     && m.Date >= request.StartDate.Date
                     && m.Date <= request.EndDate.Date)
            .ToListAsync(cancellationToken);

        if (!metrics.Any())
        {
            _logger.LogInformation("No metrics found for Campaign {CampaignId}", request.CampaignId);
            return null;
        }

        // EN: Aggregate totals
        // VI: Tổng hợp tổng cộng
        var totalImpressions = metrics.Sum(m => m.Impressions);
        var totalClicks = metrics.Sum(m => m.Clicks);
        var totalConversions = metrics.Sum(m => m.Conversions);
        var totalSpend = metrics.Sum(m => m.Spend);
        var totalRevenue = metrics.Sum(m => m.Revenue);

        // EN: Calculate aggregate KPIs
        // VI: Tính toán KPIs tổng hợp
        var ctr = totalImpressions > 0 ? (decimal)totalClicks / totalImpressions * 100 : 0;
        var cpc = totalClicks > 0 ? totalSpend / totalClicks : 0;
        var cpa = totalConversions > 0 ? totalSpend / totalConversions : 0;
        var roas = totalSpend > 0 ? totalRevenue / totalSpend : 0;

        return new CampaignMetricsDto
        {
            CampaignId = request.CampaignId,
            StartDate = request.StartDate,
            EndDate = request.EndDate,
            TotalImpressions = totalImpressions,
            TotalClicks = totalClicks,
            TotalConversions = totalConversions,
            TotalSpend = totalSpend,
            TotalRevenue = totalRevenue,
            CTR = ctr,
            CPC = cpc,
            CPA = cpa,
            ROAS = roas
        };
    }
}
