using MediatR; using FluentResults; using Microsoft.EntityFrameworkCore; using NexusReader.Application.DTOs.User; using NexusReader.Data.Persistence; namespace NexusReader.Application.Queries.User; public class GetUserProfileQueryHandler : IRequestHandler> { private readonly IDbContextFactory _dbContextFactory; public GetUserProfileQueryHandler(IDbContextFactory dbContextFactory) { _dbContextFactory = dbContextFactory; } public async Task> Handle(GetUserProfileQuery request, CancellationToken cancellationToken) { using var dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken); var profile = await dbContext.Users .Where(u => u.Id == request.UserId) .Select(u => new UserProfileDto { Email = u.Email ?? string.Empty, AITokensUsed = u.AITokensUsed, TenantId = u.TenantId != null && u.TenantId.Length == 36 ? new Guid(u.TenantId) : Guid.Empty, Plan = u.SubscriptionPlan != null ? new SubscriptionPlanDto { Id = u.SubscriptionPlan.Id, Name = u.SubscriptionPlan.PlanName, AITokenLimit = u.SubscriptionPlan.AITokenLimit, MonthlyPrice = u.SubscriptionPlan.MonthlyPrice } : new SubscriptionPlanDto(), AverageQuizScore = u.QuizResults.Any(q => q.TotalQuestions > 0) ? (int)u.QuizResults.Where(q => q.TotalQuestions > 0).Average(q => (double)q.Score / q.TotalQuestions * 100) : 0, LastReadBook = u.Ebooks.OrderByDescending(e => e.LastReadDate).Select(e => new LastReadBookDto { Id = e.Id, Title = e.Title, Author = new AuthorDto { Id = e.Author.Id, Name = e.Author.Name }, CoverUrl = e.CoverUrl, Progress = e.Progress, LastChapter = e.LastChapter ?? "Rozpoczynanie...", LastChapterIndex = e.LastChapterIndex, Description = e.Description, IsReadyForReading = e.IsReadyForReading }).FirstOrDefault(), Roles = dbContext.UserRoles .Where(ur => ur.UserId == u.Id) .Join(dbContext.Roles, ur => ur.RoleId, r => r.Id, (ur, r) => r.Name!) .ToArray() }) .FirstOrDefaultAsync(cancellationToken); if (profile == null) { return Result.Fail("Profile not found."); } return Result.Ok(profile); } }