using QRRapidoApp.Models.DTOs; using QRRapidoApp.Services; namespace QRRapidoApp.Services { public class QuotaValidator : IQuotaValidator { private readonly IUserService _userService; private readonly ILogger _logger; public QuotaValidator(IUserService userService, ILogger logger) { _userService = userService; _logger = logger; } public async Task<(bool CanProceed, string? ErrorCode, string? ErrorMessage)> ValidateQuotaAsync(UserRequesterContext context) { if (!context.IsAuthenticated) { // Se não tem Cookie de DeviceId, permitimos (limpar cookie funciona) if (string.IsNullOrEmpty(context.DeviceId)) { return (true, null, null); } // Verifica no banco se este DeviceId já estourou o limite de 3 // (Removi a trava por IP aqui para permitir seu teste com limpeza de cookies) var canGenerate = await _userService.CheckAnonymousLimitAsync("ignore_ip", context.DeviceId); if (!canGenerate) { return (false, "LIMIT_REACHED", "Limite diário atingido. Limpe os cookies ou cadastre-se!"); } return (true, null, null); } var user = await _userService.GetUserAsync(context.UserId!); if (user == null) return (false, "UNAUTHORIZED", "Usuário não encontrado."); if (user.FreeQRsUsed < 5 || user.Credits > 0) return (true, null, null); return (false, "INSUFFICIENT_CREDITS", "Saldo insuficiente. Adquira mais créditos."); } public async Task RegisterUsageAsync(UserRequesterContext context, string qrId, int cost = 1) { try { if (!context.IsAuthenticated) { // Registra apenas via DeviceId para o seu teste funcionar await _userService.RegisterAnonymousUsageAsync("ignore_ip", context.DeviceId ?? "temp_id", qrId); return; } if (cost <= 0) return; var user = await _userService.GetUserAsync(context.UserId!); if (user == null) return; if (user.FreeQRsUsed < 5) await _userService.IncrementFreeUsageAsync(context.UserId!); else await _userService.DeductCreditAsync(context.UserId!); } catch (Exception ex) { _logger.LogError(ex, "Error registering usage in QuotaValidator"); } } } }