using Femto.Common.Domain;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace Femto.Common.Infrastructure;

public class DDDPipelineBehaviour<TRequest, TResponse>(
    DbContext context,
    IPublisher publisher,
    ILogger<DDDPipelineBehaviour<TRequest, TResponse>> logger
) : IPipelineBehavior<TRequest, TResponse>
    where TRequest : notnull
{
    public async Task<TResponse> Handle(
        TRequest request,
        RequestHandlerDelegate<TResponse> next,
        CancellationToken cancellationToken
    )
    {
        logger.LogDebug("handling request {Type}", typeof(TRequest).Name);
        var response = await next(cancellationToken);
        
        var hasChanges = context.ChangeTracker.HasChanges();
        logger.LogDebug("request handled. Changes? {HasChanges}", hasChanges);
        
        if (context.ChangeTracker.HasChanges())
        {
            await context.EmitDomainEvents(logger, publisher, cancellationToken);
            logger.LogDebug("saving changes");
            await context.SaveChangesAsync(cancellationToken);
        }
        return response;
    }
}
