// EN: Product repository implementation.
// VI: Implementation repository Product.

using CatalogService.Domain.AggregatesModel.ProductAggregate;
using CatalogService.Domain.SeedWork;
using Microsoft.EntityFrameworkCore;

namespace CatalogService.Infrastructure.Repositories;

/// <summary>
/// EN: Repository implementation for Product aggregate.
/// VI: Implementation repository cho Product aggregate.
/// </summary>
public class ProductRepository : IProductRepository
{
    private readonly CatalogContext _context;

    public IUnitOfWork UnitOfWork => _context;

    public ProductRepository(CatalogContext context)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
    }

    public Product Add(Product product)
    {
        return _context.Products.Add(product).Entity;
    }

    public void Update(Product product)
    {
        _context.Entry(product).State = EntityState.Modified;
    }

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

    public async Task<IEnumerable<Product>> GetByShopIdAsync(Guid shopId, CancellationToken cancellationToken = default)
    {
        return await _context.Products
            .Where(p => p.ShopId == shopId)
            .ToListAsync(cancellationToken);
    }

    public async Task<IEnumerable<Product>> GetByTypeAsync(Guid shopId, ProductType type, CancellationToken cancellationToken = default)
    {
        return await _context.Products
            .Where(p => p.ShopId == shopId && p.TypeId == type.Id)
            .ToListAsync(cancellationToken);
    }
}
