using QRRapidoApp.Models.DTOs; using QRRapidoApp.Models.ViewModels; using System.Security.Cryptography; using System.Text; namespace QRRapidoApp.Services { public class QRBusinessManager : IQRBusinessManager { private readonly IQRCodeService _qrService; private readonly IQuotaValidator _quotaValidator; private readonly IUserService _userService; private readonly ILogger _logger; public QRBusinessManager( IQRCodeService qrService, IQuotaValidator quotaValidator, IUserService userService, ILogger logger) { _qrService = qrService; _quotaValidator = quotaValidator; _userService = userService; _logger = logger; } public async Task ProcessGenerationAsync(QRGenerationRequest request, UserRequesterContext context) { var quotaCheck = await _quotaValidator.ValidateQuotaAsync(context); if (!quotaCheck.CanProceed) { return new QRResponseDto { Success = false, ErrorCode = quotaCheck.ErrorCode, Message = quotaCheck.ErrorMessage }; } // Garantir que campos básicos não sejam nulos para o Hash string content = request.Content ?? ""; string type = request.Type ?? "url"; string corner = request.CornerStyle ?? "square"; string primary = request.PrimaryColor ?? "#000000"; string bg = request.BackgroundColor ?? "#FFFFFF"; var contentHash = ComputeSha256Hash(content + type + corner + primary + bg); if (context.IsAuthenticated) { var duplicate = await _userService.FindDuplicateQRAsync(context.UserId!, contentHash); if (duplicate != null) { var user = await _userService.GetUserAsync(context.UserId!); return new QRResponseDto { Success = true, QRCodeBase64 = duplicate.QRCodeBase64, QRId = duplicate.Id, FromCache = true, Message = "Recuperado do histórico (sem custo)", RemainingCredits = user?.Credits ?? 0, RemainingFreeQRs = 5 - (user?.FreeQRsUsed ?? 5) }; } } request.IsPremium = context.IsAuthenticated; var generationResult = await _qrService.GenerateRapidAsync(request); if (!generationResult.Success) { return new QRResponseDto { Success = false, Message = generationResult.ErrorMessage }; } int cost = context.IsAuthenticated ? 1 : 0; await _userService.SaveQRToHistoryAsync(context.UserId, generationResult, cost); await _quotaValidator.RegisterUsageAsync(context, generationResult.QRId, cost); int credits = 0, freeUsed = 0; if (context.IsAuthenticated) { var user = await _userService.GetUserAsync(context.UserId!); credits = user?.Credits ?? 0; freeUsed = user?.FreeQRsUsed ?? 5; } return new QRResponseDto { Success = true, QRCodeBase64 = generationResult.QRCodeBase64, QRId = generationResult.QRId, GenerationTimeMs = generationResult.GenerationTimeMs, RemainingCredits = credits, RemainingFreeQRs = context.IsAuthenticated ? (5 - freeUsed) : 3 }; } private string ComputeSha256Hash(string rawData) { using (SHA256 sha256Hash = SHA256.Create()) { byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(rawData)); StringBuilder builder = new StringBuilder(); for (int i = 0; i < bytes.Length; i++) builder.Append(bytes[i].ToString("x2")); return builder.ToString(); } } } }