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

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

namespace FnbEngine.Infrastructure.Repositories;

public class ReservationRepository : IReservationRepository
{
    private readonly FnbContext _context;

    public IUnitOfWork UnitOfWork => _context;

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

    public async Task<Reservation> AddAsync(Reservation reservation, CancellationToken cancellationToken = default)
    {
        return (await _context.Reservations.AddAsync(reservation, cancellationToken)).Entity;
    }

    public void Update(Reservation reservation)
    {
        _context.Entry(reservation).State = EntityState.Modified;
    }

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

    public async Task<IEnumerable<Reservation>> GetByShopAsync(Guid shopId, DateTime? date = null, CancellationToken cancellationToken = default)
    {
        var query = _context.Reservations.Where(r => r.ShopId == shopId);

        if (date.HasValue)
        {
            var startOfDay = date.Value.Date;
            var endOfDay = startOfDay.AddDays(1);
            query = query.Where(r => r.ReservationTime >= startOfDay && r.ReservationTime < endOfDay);
        }

        return await query.OrderBy(r => r.ReservationTime).ToListAsync(cancellationToken);
    }
}
