using Application.Common.Results; using Application.DTOs; using Application.Errors; using Application.Interfaces; using Application.Models; using Application.Validators; using Domain.Interface; namespace Application.Services; public class UserService( IUnitOfWork unitOfWork, UserUpdateRequestValidator userUpdateRequestValidator, IUserRepository userRepository, IUserRoleRepository userRoleRepository) : IUserService { public async Task>> GetAsync(int pageNumber = 1, int pageSize = 10) { try { // fetch all users var users = await userRepository.GetAllAsync(); var totalCount = users.Count; var pagedItems = users .Skip((pageNumber - 1) * pageSize) .Take(pageSize) .Select(user => new UserDto { Id = user.Id, Email = user.Email, Username = user.Username, LastLogin = user.LastLogin, Roles = user.UserRoles.Select(x => x.Role?.Name ?? "Unknown").ToList() }) .ToList(); var pageResult = new PagedResult { Items = pagedItems, TotalCount = totalCount, PageNumber = pageNumber, PageSize = pageSize }; return Result.Success(pageResult); } catch (Exception e) { Console.WriteLine(e); throw; } } public async Task> UpdateAsync(UserUpdateRequest userUpdateRequest) { try { // validate request var validationResult = await userUpdateRequestValidator.ValidateAsync(userUpdateRequest); if (!validationResult.IsValid) { var errors = validationResult.Errors.Select(a => a.ErrorMessage); return Result.Failure(UserError.CreateInvalidUserUpdateRequestError(errors)); } // check if a user exists var user = await userRepository.GetByIdAsync(userUpdateRequest.Id); if (user == null) return Result.Failure(UserError.UserNotFound); // update user user.Username = userUpdateRequest.Username; user.Email = userUpdateRequest.Email; userRepository.Update(user); await unitOfWork.CommitAsync(); return Result.Success("User updated successfully"); } catch (Exception e) { Console.WriteLine(e); throw; } } public async Task> DeleteAsync(int id, int currentUserId) { try { // Prevent users from deleting themselves if (id == currentUserId) return Result.Failure(UserError.CannotDeleteYourself); var user = await userRepository.GetByIdAsync(id); if (user == null) return Result.Failure(UserError.UserNotFound); userRepository.Delete(user); await unitOfWork.CommitAsync(); return Result.Success("User deleted successfully"); } catch (Exception e) { Console.WriteLine(e); throw; } } public async Task> GetUserByIdAsync(int id) { try { var user = await userRepository.GetByIdAsync(id); if (user is null) return Result.Failure(UserError.UserNotFound); var userDetails = new UserDto { Id = user.Id, Email = user.Email, Username = user.Username, LastLogin = user.LastLogin, Roles = user.UserRoles.Select(x => x.Role?.Name ?? "Unknown").ToList() }; return Result.Success(userDetails); } catch (Exception e) { Console.WriteLine(e); throw; } } public async Task> AssignRoleAsync(AssingRoleRequest roleRequest) { try { var isUserHasRole = userRoleRepository.HasRoleAsync(roleRequest.UserId, roleRequest.RoleId); if (isUserHasRole.Result) return Result.Failure(UserError.UserAlreadyHasRole); var result = await userRoleRepository.AddRoleAsync(roleRequest.UserId, roleRequest.RoleId); return result ? Result.Success("Role assigned successfully") : Result.Failure(UserError.FailedToAssignRole); } catch (Exception e) { Console.WriteLine(e); throw; } } public async Task> RevokeRoleAsync(AssingRoleRequest roleRequest) { try { var isUserHasRole = userRoleRepository.HasRoleAsync(roleRequest.UserId, roleRequest.RoleId); if (!isUserHasRole.Result) return Result.Failure(UserError.UserHasNoRole); var result = await userRoleRepository.RemoveRoleAsync(roleRequest.UserId, roleRequest.RoleId); return result ? Result.Success("Role revoked successfully") : Result.Failure(UserError.FailedToRevokeRole); } catch (Exception e) { Console.WriteLine(e); throw; } } }