using AutoMapper; using GreenHome.Application; using Microsoft.EntityFrameworkCore; namespace GreenHome.Infrastructure; public sealed class DeviceService : IDeviceService { private readonly GreenHomeDbContext dbContext; private readonly IMapper mapper; public DeviceService(GreenHomeDbContext dbContext, IMapper mapper) { this.dbContext = dbContext; this.mapper = mapper; } public async Task AddDeviceAsync(DeviceDto dto, CancellationToken cancellationToken) { var entity = mapper.Map(dto); dbContext.Devices.Add(entity); await dbContext.SaveChangesAsync(cancellationToken); return entity.Id; } public async Task> ListAsync(CancellationToken cancellationToken) { var items = await dbContext.Devices .AsNoTracking() .Include(d => d.User) .OrderBy(d => d.DeviceName) .ToListAsync(cancellationToken); return mapper.Map>(items); } public async Task GetDeviceId(string deviceName,CancellationToken cancellationToken) { var item = await dbContext.Devices .AsNoTracking() .Include(d => d.User) .Where(d=>d.DeviceName==deviceName) .FirstOrDefaultAsync(cancellationToken); return mapper.Map(item); } public async Task> GetUserDevicesAsync(int userId, CancellationToken cancellationToken) { var items = await dbContext.Devices .AsNoTracking() .Include(d => d.User) .Where(d => d.UserId == userId) .OrderBy(d => d.DeviceName) .ToListAsync(cancellationToken); return mapper.Map>(items); } public async Task> GetDevicesAsync(DeviceFilter filter, CancellationToken cancellationToken) { if (!filter.UserId.HasValue) { throw new ArgumentException("UserId is required", nameof(filter)); } // Get user and role var user = await dbContext.Users .AsNoTracking() .FirstOrDefaultAsync(u => u.Id == filter.UserId.Value, cancellationToken); if (user == null) { return new PagedResult { Items = Array.Empty(), TotalCount = 0, Page = filter.Page, PageSize = filter.PageSize }; } // Build query based on role IQueryable query = dbContext.Devices .AsNoTracking() .Include(d => d.User); if (user.Role == Domain.UserRole.Normal) { // Normal user: only own devices query = query.Where(d => d.UserId == user.Id); } else if (user.Role == Domain.UserRole.Supervisor) { // Supervisor: devices assigned to them query = query.Where(d => d.DeviceUsers.Any(du => du.UserId == user.Id)); } // Admin: all devices (no filter) // Apply search filter if (!string.IsNullOrWhiteSpace(filter.Search)) { var searchTerm = filter.Search.Trim().ToLower(); query = query.Where(d => d.DeviceName.ToLower().Contains(searchTerm) || d.User.Name.ToLower().Contains(searchTerm) || d.User.Family.ToLower().Contains(searchTerm) || d.Location.ToLower().Contains(searchTerm)); } // Get total count var totalCount = await query.CountAsync(cancellationToken); // Apply pagination var items = await query .OrderBy(d => d.DeviceName) .Skip((filter.Page - 1) * filter.PageSize) .Take(filter.PageSize) .ToListAsync(cancellationToken); return new PagedResult { Items = mapper.Map>(items), TotalCount = totalCount, Page = filter.Page, PageSize = filter.PageSize }; } }