using Microsoft.EntityFrameworkCore;
using PowderCoating.Core.Entities;
using PowderCoating.Core.Enums;
using PowderCoating.Core.Interfaces.Repositories;
using PowderCoating.Infrastructure.Data;
namespace PowderCoating.Infrastructure.Repositories;
///
/// Typed repository for that provides IgnoreQueryFilters-based
/// lookups by entity FK (InvoiceId, QuoteId, JobId).
///
public class NotificationLogRepository : Repository, INotificationLogRepository
{
public NotificationLogRepository(ApplicationDbContext context) : base(context) { }
///
public async Task GetLatestForInvoiceAsync(int invoiceId) =>
await _context.Set()
.IgnoreQueryFilters()
.Where(n => n.InvoiceId == invoiceId)
.OrderByDescending(n => n.SentAt)
.FirstOrDefaultAsync();
///
public async Task> GetAllForInvoiceAsync(int invoiceId) =>
await _context.Set()
.IgnoreQueryFilters()
.Where(n => n.InvoiceId == invoiceId)
.OrderByDescending(n => n.SentAt)
.ToListAsync();
///
public async Task GetLatestForQuoteAsync(int quoteId) =>
await _context.Set()
.IgnoreQueryFilters()
.Where(n => n.QuoteId == quoteId)
.OrderByDescending(n => n.SentAt)
.FirstOrDefaultAsync();
///
public async Task> GetAllForQuoteAsync(int quoteId) =>
await _context.Set()
.IgnoreQueryFilters()
.Where(n => n.QuoteId == quoteId)
.OrderByDescending(n => n.SentAt)
.ToListAsync();
///
public async Task GetLatestForJobAsync(int jobId) =>
await _context.Set()
.IgnoreQueryFilters()
.Where(n => n.JobId == jobId)
.OrderByDescending(n => n.SentAt)
.FirstOrDefaultAsync();
///
public async Task> GetAllForJobAsync(int jobId) =>
await _context.Set()
.IgnoreQueryFilters()
.Where(n => n.JobId == jobId)
.OrderByDescending(n => n.SentAt)
.ToListAsync();
///
public async Task<(List Items, int TotalCount)> GetPagedFilteredAsync(
int pageNumber, int pageSize,
string? searchTerm = null,
NotificationChannel? channel = null,
NotificationStatus? status = null,
NotificationType? type = null,
int? jobId = null,
string sortColumn = "SentAt",
string sortDirection = "desc")
{
var query = _dbSet
.AsNoTracking()
.Include(n => n.Customer)
.Include(n => n.Job)
.Include(n => n.Quote)
.AsQueryable();
if (jobId.HasValue)
query = query.Where(n => n.JobId == jobId.Value);
if (!string.IsNullOrWhiteSpace(searchTerm))
{
var s = searchTerm.ToLower();
query = query.Where(n =>
n.RecipientName.ToLower().Contains(s) ||
n.Recipient.ToLower().Contains(s) ||
(n.Subject != null && n.Subject.ToLower().Contains(s)) ||
(n.Job != null && n.Job.JobNumber.ToLower().Contains(s)) ||
(n.Quote != null && n.Quote.QuoteNumber.ToLower().Contains(s)));
}
if (channel.HasValue)
query = query.Where(n => n.Channel == channel.Value);
if (status.HasValue)
query = query.Where(n => n.Status == status.Value);
if (type.HasValue)
query = query.Where(n => n.NotificationType == type.Value);
var totalCount = await query.CountAsync();
query = (sortColumn, sortDirection) switch
{
("RecipientName", "asc") => query.OrderBy(n => n.RecipientName),
("RecipientName", _) => query.OrderByDescending(n => n.RecipientName),
("Channel", "asc") => query.OrderBy(n => n.Channel),
("Channel", _) => query.OrderByDescending(n => n.Channel),
("Status", "asc") => query.OrderBy(n => n.Status),
("Status", _) => query.OrderByDescending(n => n.Status),
("Type", "asc") => query.OrderBy(n => n.NotificationType),
("Type", _) => query.OrderByDescending(n => n.NotificationType),
(_, "asc") => query.OrderBy(n => n.SentAt),
_ => query.OrderByDescending(n => n.SentAt)
};
var items = await query
.Skip((pageNumber - 1) * pageSize)
.Take(pageSize)
.ToListAsync();
return (items, totalCount);
}
}