using Microsoft.EntityFrameworkCore; using UniVerse.Application.DTOs.Common; using UniVerse.Application.DTOs.Users; using UniVerse.Application.Interfaces; using UniVerse.Application.Mappings; using UniVerse.Domain.Enums; using UniVerse.Domain.Exceptions; using UniVerse.Infrastructure.Data; namespace UniVerse.Infrastructure.Services; public class UserService : IUserService { private readonly AppDbContext _db; private readonly IGamificationService _gamification; public UserService(AppDbContext db, IGamificationService gamification) { _db = db; _gamification = gamification; } public async Task GetByIdAsync(int id) { var user = await _db.Users.FindAsync(id) ?? throw new NotFoundException("User", id); return user.ToDto(_gamification.CalculateLevel(user.Xp)); } public async Task UpdateProfileAsync(int id, UpdateUserRequest request) { var user = await _db.Users.FindAsync(id) ?? throw new NotFoundException("User", id); if (request.DisplayName != null) user.DisplayName = request.DisplayName; if (request.AvatarUrl != null) user.AvatarUrl = request.AvatarUrl; user.UpdatedAt = DateTime.UtcNow; await _db.SaveChangesAsync(); return user.ToDto(_gamification.CalculateLevel(user.Xp)); } public async Task GetStatsAsync(int id) { var user = await _db.Users.FindAsync(id) ?? throw new NotFoundException("User", id); var totalLectures = await _db.LectureEnrollments.CountAsync(e => e.UserId == id); var attended = await _db.LectureEnrollments.CountAsync(e => e.UserId == id && e.Attended); var reviews = await _db.Reviews.CountAsync(r => r.UserId == id); var achievements = await _db.UserAchievements.CountAsync(ua => ua.UserId == id); return new UserStatsDto( totalLectures, attended, reviews, user.Xp, user.Coins, _gamification.CalculateLevel(user.Xp), achievements ); } public async Task> GetAllAsync(UserFilterRequest filter) { var query = _db.Users.AsQueryable(); if (!string.IsNullOrEmpty(filter.Search)) { var search = filter.Search.ToLower(); query = query.Where(u => u.Email.ToLower().Contains(search) || (u.DisplayName != null && u.DisplayName.ToLower().Contains(search))); } if (filter.Role.HasValue) query = query.Where(u => u.Role == filter.Role.Value); if (filter.IsActive.HasValue) query = query.Where(u => u.IsActive == filter.IsActive.Value); var total = await query.CountAsync(); var users = await query .OrderByDescending(u => u.CreatedAt) .Skip((filter.Page - 1) * filter.PageSize) .Take(filter.PageSize) .ToListAsync(); var items = users.Select(u => u.ToDto(_gamification.CalculateLevel(u.Xp))).ToList(); return PagedResult.Create(items, total, filter.Page, filter.PageSize); } public async Task SetRoleAsync(int id, UserRole role) { var user = await _db.Users.FindAsync(id) ?? throw new NotFoundException("User", id); user.Role = role; user.UpdatedAt = DateTime.UtcNow; await _db.SaveChangesAsync(); } public async Task SetActiveAsync(int id, bool isActive) { var user = await _db.Users.FindAsync(id) ?? throw new NotFoundException("User", id); user.IsActive = isActive; user.UpdatedAt = DateTime.UtcNow; await _db.SaveChangesAsync(); } }