using Microsoft.EntityFrameworkCore;
using StorageService.Domain.SeedWork;

// EN: Alias to avoid collision with System.IO.FileShare
// VI: Alias để tránh xung đột với System.IO.FileShare
using DomainFileShare = StorageService.Domain.AggregatesModel.FileShareAggregate.FileShare;
using StorageService.Domain.AggregatesModel.FileShareAggregate;

namespace StorageService.Infrastructure.Persistence.Repositories;

/// <summary>
/// EN: Repository implementation for FileShare aggregate.
/// VI: Implementation repository cho FileShare aggregate.
/// </summary>
public class FileShareRepository : IFileShareRepository
{
    private readonly StorageServiceContext _context;

    public FileShareRepository(StorageServiceContext context)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
    }

    public IUnitOfWork UnitOfWork => _context;

    /// <inheritdoc />
    public async Task<DomainFileShare?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default)
    {
        return await _context.FileShares
            .FirstOrDefaultAsync(x => x.Id == id, cancellationToken);
    }

    /// <inheritdoc />
    public async Task<DomainFileShare?> GetByTokenAsync(string token, CancellationToken cancellationToken = default)
    {
        return await _context.FileShares
            .FirstOrDefaultAsync(x => x.ShareToken == token, cancellationToken);
    }

    /// <inheritdoc />
    public async Task<IEnumerable<DomainFileShare>> GetByFileIdAsync(Guid fileId, CancellationToken cancellationToken = default)
    {
        return await _context.FileShares
            .Where(x => x.FileId == fileId && x.Status == FileShareStatus.Active)
            .OrderByDescending(x => x.CreatedAt)
            .ToListAsync(cancellationToken);
    }

    /// <inheritdoc />
    public async Task<IEnumerable<DomainFileShare>> GetBySharedByAsync(string userId, CancellationToken cancellationToken = default)
    {
        return await _context.FileShares
            .Where(x => x.SharedBy == userId)
            .OrderByDescending(x => x.CreatedAt)
            .ToListAsync(cancellationToken);
    }

    /// <inheritdoc />
    public async Task<IEnumerable<DomainFileShare>> GetSharedWithAsync(string userId, CancellationToken cancellationToken = default)
    {
        return await _context.FileShares
            .Where(x => x.SharedWith == userId && x.Status == FileShareStatus.Active)
            .OrderByDescending(x => x.CreatedAt)
            .ToListAsync(cancellationToken);
    }

    /// <inheritdoc />
    public async Task<DomainFileShare> AddAsync(DomainFileShare fileShare, CancellationToken cancellationToken = default)
    {
        await _context.FileShares.AddAsync(fileShare, cancellationToken);
        return fileShare;
    }

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