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

namespace StorageService.Infrastructure.Persistence.Repositories;

/// <summary>
/// EN: Repository implementation for UserStorageQuota aggregate.
/// VI: Repository implementation cho UserStorageQuota aggregate.
/// </summary>
public class QuotaRepository : IQuotaRepository
{
    private readonly StorageServiceContext _context;

    public IUnitOfWork UnitOfWork => _context;

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

    /// <inheritdoc />
    public async Task<UserStorageQuota> AddAsync(UserStorageQuota quota, CancellationToken cancellationToken = default)
    {
        var entry = await _context.UserStorageQuotas.AddAsync(quota, cancellationToken);
        return entry.Entity;
    }

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

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

    /// <inheritdoc />
    public async Task<UserStorageQuota?> GetByUserIdAsync(string userId, CancellationToken cancellationToken = default)
    {
        return await _context.UserStorageQuotas
            .FirstOrDefaultAsync(q => q.UserId == userId, cancellationToken);
    }

    /// <inheritdoc />
    public async Task<UserStorageQuota> GetOrCreateAsync(string userId, CancellationToken cancellationToken = default)
    {
        var quota = await GetByUserIdAsync(userId, cancellationToken);
        
        if (quota != null)
            return quota;

        // EN: Create default quota for new user / VI: Tạo quota mặc định cho user mới
        quota = new UserStorageQuota(userId);
        await AddAsync(quota, cancellationToken);
        await _context.SaveChangesAsync(cancellationToken);
        
        return quota;
    }
}
