using Microsoft.EntityFrameworkCore;

public sealed class AlertsUnacknowledgedCollector : BackgroundService
{
    // 5 minutes matches the DLQ TTL — an alert that survived escalation is still open.
    private static readonly TimeSpan UnacknowledgedThreshold = TimeSpan.FromMinutes(5);

    private readonly IServiceScopeFactory _scopes;
    private readonly ClinicalMetrics _metrics;
    private readonly ILogger<AlertsUnacknowledgedCollector> _logger;

    public AlertsUnacknowledgedCollector(
        IServiceScopeFactory scopes,
        ClinicalMetrics metrics,
        ILogger<AlertsUnacknowledgedCollector> logger)
    {
        _scopes  = scopes;
        _metrics = metrics;
        _logger  = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken ct)
    {
        using var timer = new PeriodicTimer(TimeSpan.FromSeconds(30));
        while (await timer.WaitForNextTickAsync(ct))
            await CollectAsync(ct);
    }

    private async Task CollectAsync(CancellationToken ct)
    {
        try
        {
            await using var scope = _scopes.CreateAsyncScope();
            var db     = scope.ServiceProvider.GetRequiredService<AppDbContext>();
            var cutoff = DateTimeOffset.UtcNow - UnacknowledgedThreshold;

            var count = await db.ClinicalAlerts
                .CountAsync(a => a.Severity   == AlertSeverity.Critical
                              && a.Status      == AlertStatus.Open
                              && a.TriggeredAt < cutoff, ct);

            _metrics.AlertsUnacknowledgedGauge.Set(count);

            if (count > 0)
                _logger.LogWarning(
                    "[PATIENT-SAFETY] alerts_unacknowledged_gauge={Count} " +
                    "(CRITICAL alerts open > 5 min)", count);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "AlertsUnacknowledgedCollector failed");
        }
    }
}