using Microsoft.EntityFrameworkCore;

public class AlertQualityMetricsService : IAlertQualityMetricsService
{
    private readonly AppDbContext _db;

    public AlertQualityMetricsService(AppDbContext db) => _db = db;

    public async Task<IReadOnlyList<AlertQualityMetricResponse>> ListAsync(
        AlertType? alertType, DateTimeOffset from, DateTimeOffset to)
    {
        var query = _db.AlertQualityMetrics
            .AsNoTracking()
            .Where(m => m.WindowStart >= from && m.WindowEnd <= to);

        if (alertType.HasValue)
            query = query.Where(m => m.AlertType == alertType.Value);

        var rows = await query
            .OrderByDescending(m => m.WindowStart)
            .ThenBy(m => m.AlertType)
            .ToListAsync();

        return rows.Select(Map).ToList();
    }

    public async Task<AlertQualitySummaryResponse> GetSummaryAsync(
        DateTimeOffset from, DateTimeOffset to)
    {
        var snapshots = await _db.AlertQualityMetrics
            .AsNoTracking()
            .Where(m => m.WindowStart >= from && m.WindowEnd <= to)
            .ToListAsync();

        if (snapshots.Count == 0)
        {
            return new AlertQualitySummaryResponse(
                from, to, 0, 0, 0, 0, 0, 0, 0, 0);
        }

        var totalAlerts = snapshots.Sum(s => s.TotalAlerts);
        var totalFeedback = snapshots.Sum(s => s.FeedbackCount);
        var totalAcknowledged = snapshots.Sum(s => s.AcknowledgedCount);
        var totalUseful = snapshots.Sum(s => s.FeedbackUsefulCount);
        var totalFalsePositive = snapshots.Sum(s => s.FeedbackFalsePositiveCount);
        var totalWouldAct = snapshots.Sum(s => s.FeedbackWouldActCount);

        var weightedAckSeconds = snapshots.Sum(s => s.AvgSecondsToAcknowledge * s.TotalAlerts);
        var weightedResolveSeconds = snapshots.Sum(s => s.AvgSecondsToResolution * s.ResolvedCount);

        return new AlertQualitySummaryResponse(
            PeriodStart: from,
            PeriodEnd: to,
            TotalAlerts: totalAlerts,
            TotalFeedback: totalFeedback,
            AcknowledgementRate: totalAlerts == 0 ? 0 : (double)totalAcknowledged / totalAlerts,
            FalsePositiveRate: totalFeedback == 0 ? 0 : (double)totalFalsePositive / totalFeedback,
            UsefulRate: totalFeedback == 0 ? 0 : (double)totalUseful / totalFeedback,
            WouldActRate: totalFeedback == 0 ? 0 : (double)totalWouldAct / totalFeedback,
            AvgSecondsToAcknowledge: totalAlerts == 0 ? 0 : weightedAckSeconds / totalAlerts,
            AvgSecondsToResolution: snapshots.Sum(s => s.ResolvedCount) == 0
                ? 0
                : weightedResolveSeconds / snapshots.Sum(s => s.ResolvedCount));
    }

    private static AlertQualityMetricResponse Map(AlertQualityMetric m) =>
        new(
            m.Id,
            m.AlertType.ToString(),
            m.WindowStart,
            m.WindowEnd,
            m.TotalAlerts,
            m.AcknowledgedCount,
            m.ResolvedCount,
            m.EscalatedCount,
            m.FeedbackUsefulCount,
            m.FeedbackFalsePositiveCount,
            m.FeedbackWouldActCount,
            m.FeedbackCount,
            m.AcknowledgementRate,
            m.FalsePositiveRate,
            m.UsefulRate,
            m.WouldActRate,
            m.AvgSecondsToAcknowledge,
            m.AvgSecondsToResolution,
            m.ComputedAt);
}