// EN: Repository implementation for KitchenTicket aggregate.
// VI: Triển khai repository cho aggregate KitchenTicket.

using Microsoft.EntityFrameworkCore;
using FnbEngine.Domain.AggregatesModel.KitchenAggregate;
using FnbEngine.Domain.SeedWork;

namespace FnbEngine.Infrastructure.Repositories;

/// <summary>
/// EN: Repository implementation for KitchenTicket aggregate.
/// VI: Triển khai repository cho aggregate KitchenTicket.
/// </summary>
public class KitchenTicketRepository : IKitchenTicketRepository
{
    private readonly FnbContext _context;

    public IUnitOfWork UnitOfWork => _context;

    public KitchenTicketRepository(FnbContext context)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
    }

    public async Task<KitchenTicket> AddAsync(KitchenTicket ticket, CancellationToken cancellationToken = default)
    {
        return (await _context.KitchenTickets.AddAsync(ticket, cancellationToken)).Entity;
    }

    public void Update(KitchenTicket ticket)
    {
        _context.Entry(ticket).State = EntityState.Modified;
    }

    public async Task<KitchenTicket?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default)
    {
        return await _context.KitchenTickets
            .FirstOrDefaultAsync(kt => kt.Id == id, cancellationToken);
    }

    public async Task<IEnumerable<KitchenTicket>> GetPendingByStationAsync(string? station, CancellationToken cancellationToken = default)
    {
        var query = _context.KitchenTickets
            .Where(kt => kt.Status == "Pending" || kt.Status == "InProgress");

        if (!string.IsNullOrWhiteSpace(station))
        {
            query = query.Where(kt => kt.Station == station);
        }

        return await query
            .OrderByDescending(kt => kt.Priority)
            .ThenBy(kt => kt.CreatedAt)
            .ToListAsync(cancellationToken);
    }

    public async Task<IEnumerable<KitchenTicket>> GetBySessionAsync(Guid sessionId, CancellationToken cancellationToken = default)
    {
        return await _context.KitchenTickets
            .Where(kt => kt.SessionId == sessionId)
            .OrderBy(kt => kt.CreatedAt)
            .ToListAsync(cancellationToken);
    }
}
