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

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

namespace FnbEngine.Infrastructure.Repositories;

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

    public IUnitOfWork UnitOfWork => _context;

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

    public async Task<Table> AddAsync(Table table, CancellationToken cancellationToken = default)
    {
        return (await _context.Tables.AddAsync(table, cancellationToken)).Entity;
    }

    public void Update(Table table)
    {
        _context.Entry(table).State = EntityState.Modified;
    }

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

    public async Task<IEnumerable<Table>> GetByShopAsync(Guid shopId, CancellationToken cancellationToken = default)
    {
        return await _context.Tables
            .Where(t => t.ShopId == shopId)
            .OrderBy(t => t.TableNumber)
            .ToListAsync(cancellationToken);
    }

    public async Task<Table?> GetByNumberAsync(Guid shopId, string tableNumber, CancellationToken cancellationToken = default)
    {
        return await _context.Tables
            .FirstOrDefaultAsync(t => t.ShopId == shopId && t.TableNumber == tableNumber, cancellationToken);
    }

    public async Task<Table?> GetByQrTokenAsync(string qrToken, CancellationToken cancellationToken = default)
    {
        return await _context.Tables
            .FirstOrDefaultAsync(t => t.QrToken == qrToken, cancellationToken);
    }
}
