using WhatsAppService.Domain.AggregatesModel.ConversationAggregate;

namespace WhatsAppService.API.BackgroundJobs;

/// <summary>
/// EN: Background job to check and expire conversations outside 24h window.
/// VI: Background job để kiểm tra và hết hạn conversations ngoài cửa sổ 24h.
/// </summary>
public class ConversationExpiryJob : BackgroundService
{
    private readonly IServiceProvider _serviceProvider;
    private readonly ILogger<ConversationExpiryJob> _logger;
    private readonly TimeSpan _checkInterval = TimeSpan.FromMinutes(5);

    public ConversationExpiryJob(
        IServiceProvider serviceProvider,
        ILogger<ConversationExpiryJob> logger)
    {
        _serviceProvider = serviceProvider;
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("ConversationExpiryJob started");

        while (!stoppingToken.IsCancellationRequested)
        {
            try
            {
                await ProcessExpiredConversationsAsync(stoppingToken);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error in ConversationExpiryJob");
            }

            await Task.Delay(_checkInterval, stoppingToken);
        }

        _logger.LogInformation("ConversationExpiryJob stopped");
    }

    private async Task ProcessExpiredConversationsAsync(CancellationToken cancellationToken)
    {
        using var scope = _serviceProvider.CreateScope();
        var repository = scope.ServiceProvider.GetRequiredService<IConversationRepository>();

        var expiredConversations = await repository.GetExpiredConversationsAsync(cancellationToken);
        
        if (expiredConversations.Count == 0)
        {
            return;
        }

        _logger.LogInformation("Found {Count} expired conversations", expiredConversations.Count);

        foreach (var conversation in expiredConversations)
        {
            conversation.CheckExpiry();
        }

        await repository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation("Processed {Count} expired conversations", expiredConversations.Count);
    }
}
