using MassTransit;
using Tiku.Contracts;

namespace Tiku.Infrastructure.Messaging;

public interface ISecurityEventPublisher
{
    Task AuthorizationChangedAsync(
        Guid? tenantId,
        Guid? userId,
        string changeKind,
        long version,
        string correlationId,
        CancellationToken cancellationToken = default);

    Task CapabilityChangedAsync(
        Guid tenantId,
        string moduleCode,
        string changeKind,
        long version,
        string correlationId,
        CancellationToken cancellationToken = default);

    Task MembershipChangedAsync(
        Guid tenantId,
        Guid userId,
        string previousStatus,
        string currentStatus,
        string correlationId,
        CancellationToken cancellationToken = default);
}

internal sealed class NullSecurityEventPublisher : ISecurityEventPublisher
{
    public Task AuthorizationChangedAsync(
        Guid? tenantId, Guid? userId, string changeKind, long version,
        string correlationId, CancellationToken cancellationToken = default) => Task.CompletedTask;

    public Task CapabilityChangedAsync(
        Guid tenantId, string moduleCode, string changeKind, long version,
        string correlationId, CancellationToken cancellationToken = default) => Task.CompletedTask;

    public Task MembershipChangedAsync(
        Guid tenantId, Guid userId, string previousStatus, string currentStatus,
        string correlationId, CancellationToken cancellationToken = default) => Task.CompletedTask;
}

internal sealed class MassTransitSecurityEventPublisher(IPublishEndpoint publishEndpoint) : ISecurityEventPublisher
{
    public Task AuthorizationChangedAsync(
        Guid? tenantId, Guid? userId, string changeKind, long version,
        string correlationId, CancellationToken cancellationToken = default) =>
        publishEndpoint.Publish(new AuthorizationStateChangedV1(
            Guid.NewGuid(), tenantId, userId, changeKind, version,
            DateTimeOffset.UtcNow, correlationId), cancellationToken);

    public Task CapabilityChangedAsync(
        Guid tenantId, string moduleCode, string changeKind, long version,
        string correlationId, CancellationToken cancellationToken = default) =>
        publishEndpoint.Publish(new TenantCapabilityChangedV1(
            Guid.NewGuid(), tenantId, moduleCode, changeKind, version,
            DateTimeOffset.UtcNow, correlationId), cancellationToken);

    public Task MembershipChangedAsync(
        Guid tenantId, Guid userId, string previousStatus, string currentStatus,
        string correlationId, CancellationToken cancellationToken = default) =>
        publishEndpoint.Publish(new MembershipLifecycleChangedV1(
            Guid.NewGuid(), tenantId, userId, previousStatus, currentStatus,
            DateTimeOffset.UtcNow, correlationId), cancellationToken);
}
