using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using StreakBot.Data; namespace StreakBot.Services; public class MonthlyRestoreBackgroundService : BackgroundService { private readonly IServiceScopeFactory _scopeFactory; private readonly ILogger _logger; private readonly TimeSpan _checkInterval = TimeSpan.FromHours(24); private int _lastResetMonth = -1; public MonthlyRestoreBackgroundService( IServiceScopeFactory scopeFactory, ILogger logger) { _scopeFactory = scopeFactory; _logger = logger; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { try { if (_lastResetMonth == -1) { var now = DateTime.UtcNow; _lastResetMonth = now.Month; } else { await CheckAndResetMonthlyRestoresAsync(); } } catch (Exception ex) { _logger.LogError(ex, "Error checking monthly restore reset"); } await Task.Delay(_checkInterval, stoppingToken); } } private async Task CheckAndResetMonthlyRestoresAsync() { var now = DateTime.UtcNow; var currentMonth = now.Month; // Only reset once per month (when the month changes) if (_lastResetMonth != currentMonth) { using var scope = _scopeFactory.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); var streaks = await context.Streaks.ToListAsync(); foreach (var streak in streaks) { streak.MonthlyRestores = 5; } if (context.ChangeTracker.HasChanges()) { var count = await context.SaveChangesAsync(); _logger.LogInformation("Reset monthly restores for {Count} streak(s)", count); } _lastResetMonth = currentMonth; } } }