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

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

namespace FnbEngine.Infrastructure.Repositories;

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

    public IUnitOfWork UnitOfWork => _context;

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

    public async Task<Session> AddAsync(Session session, CancellationToken cancellationToken = default)
    {
        return (await _context.Sessions.AddAsync(session, cancellationToken)).Entity;
    }

    public void Update(Session session)
    {
        _context.Entry(session).State = EntityState.Modified;
    }

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

    public async Task<Session?> GetActiveByTableAsync(Guid tableId, CancellationToken cancellationToken = default)
    {
        return await _context.Sessions
            .Where(s => s.TableId == tableId && s.Status == "Active")
            .OrderByDescending(s => s.StartedAt)
            .FirstOrDefaultAsync(cancellationToken);
    }

    public async Task<IEnumerable<Session>> GetByShopAsync(Guid shopId, CancellationToken cancellationToken = default)
    {
        return await _context.Sessions
            .Where(s => s.ShopId == shopId)
            .OrderByDescending(s => s.StartedAt)
            .ToListAsync(cancellationToken);
    }
}
