namespace DocuMed.Repository.Repositories.Base;
public class RepositoryWrapper(ApplicationContext context, ICurrentUserService currentUserService)
    : IRepositoryWrapper
{
    private IDbContextTransaction? _currentTransaction;

    public IBaseRepository<T> SetRepository<T>() where T : ApiEntity => new BaseRepository<T>(context, currentUserService);
    

    public async Task RollBackAsync(CancellationToken cancellationToken)
    {
        if (_currentTransaction == null)
            throw new ArgumentNullException(nameof(_currentTransaction));
        await _currentTransaction.RollbackAsync(cancellationToken);
    }
    public async Task CommitAsync(CancellationToken cancellationToken)
    {
        if (_currentTransaction == null)
            throw new ArgumentNullException(nameof(_currentTransaction));
        await _currentTransaction.CommitAsync(cancellationToken);
    }
    public async Task BeginTransaction(CancellationToken cancellationToken)
    {
        _currentTransaction = await context.Database.BeginTransactionAsync(cancellationToken);
    }
    public async Task SaveChangesAsync(CancellationToken cancellationToken = default)
    {
        SetAuditables();
        await context.SaveChangesAsync(cancellationToken);
    }

    private void SetAuditables()
    {
        IEnumerable<EntityEntry<IApiEntity>> entries = context.ChangeTracker.Entries<IApiEntity>();
        foreach (EntityEntry<IApiEntity> entity in entries)
        {
            if (entity.State == EntityState.Added)
            {
                entity.Property(e => e.CreatedAt)
                    .CurrentValue = DateTime.Now;
                if (currentUserService.UserName != null)
                    entity.Property(e => e.CreatedBy)
                        .CurrentValue = currentUserService.UserName;
            }

            if (entity.State == EntityState.Modified)
            {
                if (!entity.Property(e => e.IsRemoved).CurrentValue)
                {
                    entity.Property(e => e.ModifiedAt)
                        .CurrentValue = DateTime.Now;
                    if (currentUserService.UserName != null)
                        entity.Property(e => e.ModifiedBy)
                            .CurrentValue = currentUserService.UserName;
                }
            }
        }
    }
    public void Dispose()
    {
        _currentTransaction?.Dispose();
        context?.Dispose();
    }
}
