using System.Reflection;
using System.Text.Json;
using Femto.Common.Attributes;
using Femto.Common.Integration;
using Microsoft.Extensions.DependencyInjection;

namespace Femto.Common.Infrastructure.Outbox;

public class Outbox<TContext>(TContext context, IOutboxMessageMapping mapping) where TContext : IOutboxContext
{
    public async Task AddMessage<TMessage>(
        Guid aggregateId,
        TMessage message,
        CancellationToken cancellationToken
    )
        where TMessage : IEvent
    {
        var eventName = mapping.GetEventName(typeof(TMessage));
        if (eventName is null)
            throw new InvalidOperationException(
                $"{typeof(TMessage).Name} does not have EventType attribute"
            );

        await context.Outbox.AddAsync(
            new(message.EventId, aggregateId, eventName, JsonSerializer.Serialize(message)),
            cancellationToken
        );
    }
}
