using Health.Application.Maintenance;

namespace Health.Infrastructure.Maintenance;

public sealed class EfMaintenanceRepository(AppDbContext db) : IMaintenanceRepository
{
    private readonly AppDbContext _db = db;

    public async Task<MaintenanceCleanupResult> CleanupAsync(
        DateTime conversationCutoff,
        DateTime taskCutoff,
        DateTime utcNow,
        CancellationToken ct)
    {
        var oldConversationIds = await _db.Conversations.AsNoTracking()
            .Where(x => x.UpdatedAt < conversationCutoff)
            .Select(x => x.Id)
            .ToListAsync(ct);
        if (oldConversationIds.Count > 0)
        {
            await _db.ConversationMessages
                .Where(x => oldConversationIds.Contains(x.ConversationId))
                .ExecuteDeleteAsync(ct);
            await _db.Conversations
                .Where(x => oldConversationIds.Contains(x.Id))
                .ExecuteDeleteAsync(ct);
        }

        var verificationCodes = await _db.VerificationCodes
            .Where(x => x.ExpiresAt < utcNow)
            .ExecuteDeleteAsync(ct);

        var backgroundTasks = 0;
        backgroundTasks += await _db.ReportAnalysisTasks
            .Where(x => x.UpdatedAt < taskCutoff && (x.Status == "Completed" || x.Status == "Failed"))
            .ExecuteDeleteAsync(ct);
        backgroundTasks += await _db.DietImageAnalysisTasks
            .Where(x => x.UpdatedAt < taskCutoff && (x.Status == "Completed" || x.Status == "Failed"))
            .ExecuteDeleteAsync(ct);
        backgroundTasks += await _db.MedicationReminderTasks
            .Where(x => x.UpdatedAt < taskCutoff && (x.Status == "Completed" || x.Status == "Failed"))
            .ExecuteDeleteAsync(ct);
        backgroundTasks += await _db.NotificationOutbox
            .Where(x => x.UpdatedAt < taskCutoff)
            .ExecuteDeleteAsync(ct);
        backgroundTasks += await _db.AiWriteCommands
            .Where(x => x.UpdatedAt < taskCutoff)
            .ExecuteDeleteAsync(ct);

        return new MaintenanceCleanupResult(oldConversationIds.Count, verificationCodes, backgroundTasks);
    }
}
