using ColaFlow.Modules.Mcp.Application.Services;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace ColaFlow.Modules.Mcp.Infrastructure.BackgroundServices;

/// <summary>
/// Background service to periodically expire old PendingChanges
/// Runs every 5 minutes and marks expired changes
/// </summary>
public class PendingChangeExpirationBackgroundService : BackgroundService
{
    private readonly IServiceProvider _serviceProvider;
    private readonly ILogger<PendingChangeExpirationBackgroundService> _logger;
    private readonly TimeSpan _interval = TimeSpan.FromMinutes(5);

    public PendingChangeExpirationBackgroundService(
        IServiceProvider serviceProvider,
        ILogger<PendingChangeExpirationBackgroundService> logger)
    {
        _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("PendingChange Expiration Background Service started");

        while (!stoppingToken.IsCancellationRequested)
        {
            try
            {
                _logger.LogDebug("Running PendingChange expiration check...");

                // Create a new scope for the scoped service
                using var scope = _serviceProvider.CreateScope();
                var pendingChangeService = scope.ServiceProvider
                    .GetRequiredService<IPendingChangeService>();

                var expiredCount = await pendingChangeService.ExpireOldChangesAsync(stoppingToken);

                if (expiredCount > 0)
                {
                    _logger.LogInformation("Expired {Count} PendingChanges", expiredCount);
                }
                else
                {
                    _logger.LogDebug("No expired PendingChanges found");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error occurred while expiring PendingChanges");
            }

            // Wait for the next interval
            try
            {
                await Task.Delay(_interval, stoppingToken);
            }
            catch (TaskCanceledException)
            {
                // Expected when cancellation is requested
                break;
            }
        }

        _logger.LogInformation("PendingChange Expiration Background Service stopped");
    }
}
