using FlatRender.IdentitySvc.Application.Services.Interfaces; using FlatRender.IdentitySvc.Domain.Enums; using FlatRender.IdentitySvc.Infrastructure.Data; using FlatRender.IdentitySvc.Models.Requests; using FlatRender.IdentitySvc.Models.Responses; using Microsoft.EntityFrameworkCore; namespace FlatRender.IdentitySvc.Application.Services; public class UserService(IdentityDbContext db) : IUserService { public async Task GetMeAsync(Guid userId) { var user = await db.Users.FindAsync(userId) ?? throw new KeyNotFoundException("User not found"); return AuthService.MapUserResponse(user); } public async Task UpdateMeAsync(Guid userId, UpdateUserRequest request) { var user = await db.Users.FindAsync(userId) ?? throw new KeyNotFoundException("User not found"); if (request.FullName != null) user.FullName = request.FullName; if (request.Slogan != null) user.Slogan = request.Slogan; if (request.AboutMe != null) user.AboutMe = request.AboutMe; if (request.CompanyName != null) user.CompanyName = request.CompanyName; if (request.WebsiteName != null) user.WebsiteName = request.WebsiteName; if (request.BirthDate.HasValue) user.BirthDate = request.BirthDate; if (request.Gender != null && Enum.TryParse(request.Gender, true, out var gender)) user.Gender = gender; if (request.EmailTellMe.HasValue) user.EmailTellMe = request.EmailTellMe.Value; if (request.SmsTellMe.HasValue) user.SmsTellMe = request.SmsTellMe.Value; if (request.PushTellMe.HasValue) user.PushTellMe = request.PushTellMe.Value; if (request.TelegramTellMe.HasValue) user.TelegramTellMe = request.TelegramTellMe.Value; if (request.CountryCode != null) user.CountryCode = request.CountryCode; if (request.NationalCode != null) user.NationalCode = request.NationalCode; if (request.MethodOfIntroduction != null) user.MethodOfIntroduction = request.MethodOfIntroduction; user.UpdatedAt = DateTime.UtcNow; await db.SaveChangesAsync(); return AuthService.MapUserResponse(user); } public async Task GetBalanceAsync(Guid userId) { var user = await db.Users.FindAsync(userId) ?? throw new KeyNotFoundException("User not found"); return new BalanceResponse( user.BalanceMinor, user.AffiliateBalanceMinor, "IRR", user.DailyRemainRenderCount, user.ParallelRenderingCeiling ); } public async Task UpdateAvatarAsync(Guid userId, Guid? avatarId, string? avatarUrl) { var user = await db.Users.FindAsync(userId) ?? throw new KeyNotFoundException("User not found"); if (avatarId.HasValue) { var avatar = await db.Avatars.FindAsync(avatarId.Value); if (avatar != null) user.AvatarUrl = avatar.Url; } else if (!string.IsNullOrEmpty(avatarUrl)) { user.AvatarUrl = avatarUrl; } user.UpdatedAt = DateTime.UtcNow; await db.SaveChangesAsync(); } public async Task GetByIdAsync(Guid userId) { var user = await db.Users.FindAsync(userId) ?? throw new KeyNotFoundException("User not found"); return AuthService.MapUserResponse(user); } public async Task> SearchAsync(string? q, Guid? tenantId, int page, int pageSize) { var query = db.Users.Where(u => u.DeletedAt == null); if (tenantId.HasValue) query = query.Where(u => u.TenantId == tenantId.Value); if (!string.IsNullOrWhiteSpace(q)) query = query.Where(u => (u.Email != null && u.Email.Contains(q)) || (u.FullName != null && EF.Functions.ILike(u.FullName, $"%{q}%")) || (u.PhoneNumber != null && u.PhoneNumber.Contains(q))); var total = await query.LongCountAsync(); var users = await query .OrderByDescending(u => u.RegisterDate) .Skip((page - 1) * pageSize) .Take(pageSize) .ToListAsync(); return new PagedResponse( users.Select(AuthService.MapUserResponse).ToList(), new PaginationMeta(page, pageSize, total, total > (long)page * pageSize) ); } public async Task BanAsync(Guid userId, string reason, DateTime? unblockDate) { var user = await db.Users.FindAsync(userId) ?? throw new KeyNotFoundException("User not found"); user.BanAccount = true; user.BanReason = reason; user.UnblockDate = unblockDate; user.UpdatedAt = DateTime.UtcNow; await db.SaveChangesAsync(); } public async Task UnbanAsync(Guid userId) { var user = await db.Users.FindAsync(userId) ?? throw new KeyNotFoundException("User not found"); user.BanAccount = false; user.BanReason = null; user.UnblockDate = null; user.UpdatedAt = DateTime.UtcNow; await db.SaveChangesAsync(); } }