using Microsoft.EntityFrameworkCore;
using FacebookService.Domain.AggregatesModel.CustomerAggregate;
using FacebookService.Domain.SeedWork;

namespace FacebookService.Infrastructure.Repositories;

/// <summary>
/// EN: Repository implementation for Customer aggregate.
/// VI: Triển khai repository cho Customer aggregate.
/// </summary>
public class CustomerRepository : ICustomerRepository
{
    private readonly FacebookServiceContext _context;

    public IUnitOfWork UnitOfWork => _context;

    public CustomerRepository(FacebookServiceContext context)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
    }

    /// <inheritdoc/>
    public async Task<Customer?> GetByFacebookUserIdAsync(string facebookUserId, CancellationToken cancellationToken = default)
    {
        return await _context.Customers
            .FirstOrDefaultAsync(c => EF.Property<string>(c, "_facebookUserId") == facebookUserId, cancellationToken);
    }

    /// <inheritdoc/>
    public async Task<Customer?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default)
    {
        return await _context.Customers.FindAsync(new object[] { id }, cancellationToken);
    }

    /// <inheritdoc/>
    public Customer Add(Customer customer)
    {
        return _context.Customers.Add(customer).Entity;
    }

    /// <inheritdoc/>
    public void Update(Customer customer)
    {
        _context.Entry(customer).State = EntityState.Modified;
    }

    /// <inheritdoc/>
    public async Task<bool> ExistsByFacebookUserIdAsync(string facebookUserId, CancellationToken cancellationToken = default)
    {
        return await _context.Customers
            .AnyAsync(c => EF.Property<string>(c, "_facebookUserId") == facebookUserId, cancellationToken);
    }
}
