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

namespace StorageService.Infrastructure.Persistence.Repositories;

/// <summary>
/// EN: Repository implementation for FileVersion entity.
/// VI: Implementation repository cho entity FileVersion.
/// </summary>
public class FileVersionRepository : IFileVersionRepository
{
    private readonly StorageServiceContext _context;

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

    public IUnitOfWork UnitOfWork => _context;

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

    /// <inheritdoc />
    public async Task<IEnumerable<FileVersion>> GetByFileIdAsync(Guid fileId, CancellationToken cancellationToken = default)
    {
        return await _context.FileVersions
            .Where(x => x.FileId == fileId)
            .OrderByDescending(x => x.VersionNumber)
            .ToListAsync(cancellationToken);
    }

    /// <inheritdoc />
    public async Task<FileVersion?> GetByFileIdAndVersionAsync(Guid fileId, int versionNumber, CancellationToken cancellationToken = default)
    {
        return await _context.FileVersions
            .FirstOrDefaultAsync(x => x.FileId == fileId && x.VersionNumber == versionNumber, cancellationToken);
    }

    /// <inheritdoc />
    public async Task<FileVersion?> GetCurrentVersionAsync(Guid fileId, CancellationToken cancellationToken = default)
    {
        return await _context.FileVersions
            .FirstOrDefaultAsync(x => x.FileId == fileId && x.IsCurrent, cancellationToken);
    }

    /// <inheritdoc />
    public async Task<int> GetLatestVersionNumberAsync(Guid fileId, CancellationToken cancellationToken = default)
    {
        var latestVersion = await _context.FileVersions
            .Where(x => x.FileId == fileId)
            .MaxAsync(x => (int?)x.VersionNumber, cancellationToken);
        
        return latestVersion ?? 0;
    }

    /// <inheritdoc />
    public async Task<FileVersion> AddAsync(FileVersion version, CancellationToken cancellationToken = default)
    {
        await _context.FileVersions.AddAsync(version, cancellationToken);
        return version;
    }

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