using Microsoft.EntityFrameworkCore;
using IamService.Domain.AggregatesModel.AccessReviewAggregate;
using IamService.Domain.SeedWork;

namespace IamService.Infrastructure.Repositories;

/// <summary>
/// EN: Repository implementation for AccessReview aggregate.
/// VI: Repository implementation cho AccessReview aggregate.
/// </summary>
public class AccessReviewRepository : IAccessReviewRepository
{
    private readonly IamServiceContext _context;
    public IUnitOfWork UnitOfWork => _context;

    public AccessReviewRepository(IamServiceContext context) => _context = context;

    public AccessReview Add(AccessReview review) => _context.AccessReviews.Add(review).Entity;

    public void Update(AccessReview review) => _context.Entry(review).State = EntityState.Modified;

    public async Task<AccessReview?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default)
        => await _context.AccessReviews.FirstOrDefaultAsync(x => x.Id == id, cancellationToken);

    public async Task<AccessReview?> GetByIdWithItemsAsync(Guid id, CancellationToken cancellationToken = default)
        => await _context.AccessReviews.Include(x => x.Items).FirstOrDefaultAsync(x => x.Id == id, cancellationToken);

    public async Task<IEnumerable<AccessReview>> GetByOwnerIdAsync(Guid ownerId, CancellationToken cancellationToken = default)
        => await _context.AccessReviews
            .Where(x => EF.Property<Guid>(x, "_ownerId") == ownerId)
            .OrderByDescending(x => EF.Property<DateTime>(x, "_createdAt"))
            .ToListAsync(cancellationToken);

    public async Task<IEnumerable<AccessReview>> GetActiveReviewsAsync(CancellationToken cancellationToken = default)
        => await _context.AccessReviews
            .Where(x => EF.Property<AccessReviewStatus>(x, "_status") == AccessReviewStatus.Active)
            .ToListAsync(cancellationToken);
}
