using Microsoft.EntityFrameworkCore;
using PowderCoating.Application.Interfaces;
using PowderCoating.Infrastructure.Data;

namespace PowderCoating.Infrastructure.Services;

/// <summary>
/// Implements <see cref="IAiUsageReportService"/> by querying <c>AiUsageLogs</c> and
/// <c>QuotePhotos</c> directly via <c>ApplicationDbContext</c>. Both tables either are
/// not BaseEntity (AiUsageLog) or require cross-tenant GROUP BY aggregations that must
/// execute in SQL; this service encapsulates those queries so the controller stays clean.
/// </summary>
public class AiUsageReportService : IAiUsageReportService
{
    private readonly ApplicationDbContext _context;

    public AiUsageReportService(ApplicationDbContext context)
    {
        _context = context;
    }

    /// <inheritdoc/>
    public async Task<AiUsageReportData> GetReportDataAsync()
    {
        var now = DateTime.UtcNow;
        var todayStart  = now.Date;
        var last7Start  = todayStart.AddDays(-7);
        var last30Start = todayStart.AddDays(-30);

        var usageByCompany = await _context.AiUsageLogs
            .GroupBy(l => l.CompanyId)
            .Select(g => new AiCompanyUsage(
                g.Key,
                g.Count(l => l.CalledAt >= todayStart),
                g.Count(l => l.CalledAt >= last7Start),
                g.Count(l => l.CalledAt >= last30Start),
                g.Count()))
            .ToListAsync();

        var featureStats = await _context.AiUsageLogs
            .Where(l => l.CalledAt >= last30Start)
            .GroupBy(l => new { l.CompanyId, l.Feature })
            .Select(g => new AiFeatureStat(g.Key.CompanyId, g.Key.Feature, g.Count()))
            .ToListAsync();

        var photoCounts = await _context.QuotePhotos
            .IgnoreQueryFilters()
            .Where(p => p.IsAiAnalysisPhoto && !p.IsDeleted)
            .GroupBy(p => p.CompanyId)
            .Select(g => new { CompanyId = g.Key, Count = g.Count() })
            .ToDictionaryAsync(x => x.CompanyId, x => x.Count);

        return new AiUsageReportData(usageByCompany, featureStats, photoCounts);
    }
}
