using Microsoft.EntityFrameworkCore; using SPMS.Domain.Entities; using SPMS.Domain.Enums; using SPMS.Domain.Interfaces; namespace SPMS.Infrastructure.Persistence.Repositories; public class DeviceRepository : Repository, IDeviceRepository { public DeviceRepository(AppDbContext context) : base(context) { } public async Task GetByServiceAndTokenAsync(long serviceId, string deviceToken) { return await _dbSet.FirstOrDefaultAsync(d => d.ServiceId == serviceId && d.DeviceToken == deviceToken); } public async Task GetByIdAndServiceAsync(long id, long serviceId) { return await _dbSet.FirstOrDefaultAsync(d => d.Id == id && d.ServiceId == serviceId); } public async Task GetActiveCountByServiceAsync(long serviceId) { return await _dbSet.CountAsync(d => d.ServiceId == serviceId && d.IsActive); } public async Task> GetByPlatformAsync(long serviceId, Platform platform) { return await _dbSet .Where(d => d.ServiceId == serviceId && d.Platform == platform && d.IsActive) .ToListAsync(); } public async Task<(IReadOnlyList Items, int TotalCount)> GetPagedAsync( long? serviceId, int page, int size, Platform? platform = null, bool? pushAgreed = null, bool? isActive = null, List? tags = null, string? keyword = null, bool? marketingAgreed = null) { IQueryable query = _dbSet.Include(d => d.Service); if (serviceId.HasValue) query = query.Where(d => d.ServiceId == serviceId.Value); if (platform.HasValue) query = query.Where(d => d.Platform == platform.Value); if (pushAgreed.HasValue) query = query.Where(d => d.PushAgreed == pushAgreed.Value); if (isActive.HasValue) query = query.Where(d => d.IsActive == isActive.Value); if (marketingAgreed.HasValue) query = query.Where(d => d.MarketingAgreed == marketingAgreed.Value); if (!string.IsNullOrWhiteSpace(keyword)) { var trimmed = keyword.Trim(); if (long.TryParse(trimmed, out var deviceId)) query = query.Where(d => d.Id == deviceId || d.DeviceToken.Contains(trimmed)); else query = query.Where(d => d.DeviceToken.Contains(trimmed)); } if (tags != null && tags.Count > 0) { foreach (var tag in tags) { var tagStr = tag.ToString(); query = query.Where(d => d.Tags != null && EF.Functions.Like(d.Tags, $"%{tagStr}%")); } } var totalCount = await query.CountAsync(); var items = await query .OrderByDescending(d => d.CreatedAt) .Skip((page - 1) * size) .Take(size) .ToListAsync(); return (items, totalCount); } public async Task> GetAllFilteredAsync( long? serviceId, Platform? platform = null, bool? pushAgreed = null, bool? isActive = null, List? tags = null, string? keyword = null, bool? marketingAgreed = null) { IQueryable query = _dbSet.Include(d => d.Service); if (serviceId.HasValue) query = query.Where(d => d.ServiceId == serviceId.Value); if (platform.HasValue) query = query.Where(d => d.Platform == platform.Value); if (pushAgreed.HasValue) query = query.Where(d => d.PushAgreed == pushAgreed.Value); if (isActive.HasValue) query = query.Where(d => d.IsActive == isActive.Value); if (marketingAgreed.HasValue) query = query.Where(d => d.MarketingAgreed == marketingAgreed.Value); if (!string.IsNullOrWhiteSpace(keyword)) { var trimmed = keyword.Trim(); if (long.TryParse(trimmed, out var deviceId)) query = query.Where(d => d.Id == deviceId || d.DeviceToken.Contains(trimmed)); else query = query.Where(d => d.DeviceToken.Contains(trimmed)); } if (tags != null && tags.Count > 0) { foreach (var tag in tags) { var tagStr = tag.ToString(); query = query.Where(d => d.Tags != null && EF.Functions.Like(d.Tags, $"%{tagStr}%")); } } return await query .OrderByDescending(d => d.CreatedAt) .ToListAsync(); } public async Task> GetDevicesByTagIdAsync(long tagId) { var tagStr = tagId.ToString(); return await _dbSet .Where(d => d.Tags != null && EF.Functions.Like(d.Tags, $"%{tagStr}%")) .ToListAsync(); } public async Task> GetDeviceCountsByTagIdsAsync(IEnumerable tagIds) { var tagIdList = tagIds.ToList(); if (tagIdList.Count == 0) return new Dictionary(); var result = new Dictionary(); foreach (var tagId in tagIdList) { var tagStr = tagId.ToString(); var count = await _dbSet.CountAsync(d => d.Tags != null && EF.Functions.Like(d.Tags, $"%{tagStr}%")); result[tagId] = count; } return result; } }