using Microsoft.EntityFrameworkCore;

public class SepsisBundleMonitorService : BackgroundService
{
    private static readonly TimeSpan ScanInterval = TimeSpan.FromMinutes(5);

    private readonly IServiceProvider _services;
    private readonly ClinicalMetrics _metrics;
    private readonly ILogger<SepsisBundleMonitorService> _logger;

    public SepsisBundleMonitorService(
        IServiceProvider services,
        ClinicalMetrics metrics,
        ILogger<SepsisBundleMonitorService> logger)
    {
        _services = services;
        _metrics = metrics;
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("Sepsis bundle monitor started. ScanInterval={Interval}", ScanInterval);

        while (!stoppingToken.IsCancellationRequested)
        {
            try
            {
                await ScanOverdueBundlesAsync(stoppingToken);
            }
            catch (Exception ex) when (ex is not OperationCanceledException)
            {
                _logger.LogError(ex, "Sepsis bundle monitor error — will retry on next scan cycle");
            }

            await Task.Delay(ScanInterval, stoppingToken);
        }
    }

    internal async Task ScanOverdueBundlesAsync(CancellationToken ct)
    {
        using var scope = _services.CreateScope();
        var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();

        var overdue = await db.SepsisBundles
            .Where(b => b.ComplianceStatus == SepsisBundleComplianceStatus.InProgress
                     && b.DeadlineAt < DateTimeOffset.UtcNow)
            .ToListAsync(ct);

        if (overdue.Count == 0)
            return;

        foreach (var bundle in overdue)
        {
            bundle.ComplianceStatus = SepsisBundleComplianceStatus.NonCompliant;

            _metrics.SepsisBundleComplianceTotal
                .WithLabels("NON_COMPLIANT").Inc();

            var incompleteCount = await db.SepsisBundleElements
                .CountAsync(e => e.BundleId == bundle.Id
                              && e.Status != SepsisBundleElementStatus.Completed, ct);

            _logger.LogWarning(
                "Sepsis bundle {BundleId} for encounter {EncounterId} marked NON_COMPLIANT — " +
                "deadline {Deadline} passed with {Incomplete} incomplete elements",
                bundle.Id, bundle.EncounterId, bundle.DeadlineAt, incompleteCount);
        }

        await db.SaveChangesAsync(ct);

        _logger.LogInformation(
            "Sepsis bundle monitor marked {Count} overdue bundles as NON_COMPLIANT", overdue.Count);
    }
}
