using Distribution.Infra.UoW; using Microsoft.AspNetCore.Identity; namespace Distribution.Features.User; public class UserService(IUserRepository repo, IUnitOfWork uow) { private readonly PasswordHasher _hasher = new(); private static UserResponse ToResponse(Models.User u) => new(u.Id, u.Username, u.FullName, u.FK_RoleId, u.Role?.Name ?? string.Empty, u.FK_ReportsToUserId, u.IsActive, u.CreatedAt, u.UpdatedAt); public async Task> GetAllAsync() => (await repo.GetAllAsync()) .Where(u => u.IsActive) .Select(ToResponse) .ToList(); public async Task GetByIdAsync(Guid id) { var user = await repo.GetByIdAsync(id); if (user is null || !user.IsActive) return null; return ToResponse(user); } public async Task CreateAsync(CreateUserRequest request, CancellationToken ct = default) { var user = new Models.User { Username = request.Username, FullName = request.FullName, FK_RoleId = request.RoleId, FK_ReportsToUserId = request.ReportsToUserId }; user.PasswordHash = _hasher.HashPassword(user, request.Password); await uow.BeginAsync(ct); try { await repo.AddAsync(user); await uow.CommitAsync(ct); } catch { await uow.RollbackAsync(ct); throw; } return ToResponse(user); } public async Task UpdateAsync(Guid id, UpdateUserRequest request, CancellationToken ct = default) { var user = await repo.GetByIdAsync(id); if (user is null || !user.IsActive) return null; user.FullName = request.FullName; user.UpdatedAt = DateTime.Now; await uow.BeginAsync(ct); try { repo.Update(user); await uow.CommitAsync(ct); } catch { await uow.RollbackAsync(ct); throw; } return ToResponse(user); } public async Task AssignRoleAsync(Guid id, AssignUserRoleRequest request, CancellationToken ct = default) { var user = await repo.GetByIdAsync(id); if (user is null || !user.IsActive) return null; user.FK_RoleId = request.RoleId; user.UpdatedAt = DateTime.Now; await uow.BeginAsync(ct); try { repo.Update(user); await uow.CommitAsync(ct); } catch { await uow.RollbackAsync(ct); throw; } return ToResponse(user); } public async Task AssignScopeAsync(Guid id, AssignUserScopeRequest request, CancellationToken ct = default) { var user = await repo.GetByIdAsync(id); if (user is null || !user.IsActive) return false; await uow.BeginAsync(ct); try { await repo.ReplaceRegionScopesAsync(id, request.RegionIds); await repo.ReplaceRouteScopesAsync(id, request.RouteIds); await repo.ReplaceStoreScopesAsync(id, request.StoreIds); await uow.CommitAsync(ct); } catch { await uow.RollbackAsync(ct); throw; } return true; } public async Task DeactivateAsync(Guid id, CancellationToken ct = default) { var user = await repo.GetByIdAsync(id); if (user is null || !user.IsActive) return false; await uow.BeginAsync(ct); try { repo.Remove(user); await uow.CommitAsync(ct); } catch { await uow.RollbackAsync(ct); throw; } return true; } }