using System.Threading.Channels;

namespace Ikar.Server.Infrastructure.Push;

public enum PushDispatchKind
{
    ChatMessage = 0,
    MessageReaction = 1
}

public sealed record PushDispatchWorkItem(
    Guid ChatId,
    Guid MessageId,
    PushDispatchKind Kind = PushDispatchKind.ChatMessage,
    Guid? ActorUserId = null,
    string? ReactionEmoji = null);

public sealed class PushDispatchQueue
{
    private readonly Channel<PushDispatchWorkItem> _channel = Channel.CreateUnbounded<PushDispatchWorkItem>(
        new UnboundedChannelOptions
        {
            SingleReader = true,
            SingleWriter = false
        });

    public ValueTask EnqueueAsync(Guid chatId, Guid messageId, CancellationToken cancellationToken = default) =>
        _channel.Writer.WriteAsync(new PushDispatchWorkItem(chatId, messageId), cancellationToken);

    public ValueTask EnqueueReactionAsync(
        Guid chatId,
        Guid messageId,
        Guid reactorUserId,
        string emoji,
        CancellationToken cancellationToken = default) =>
        _channel.Writer.WriteAsync(
            new PushDispatchWorkItem(
                chatId,
                messageId,
                PushDispatchKind.MessageReaction,
                reactorUserId,
                emoji),
            cancellationToken);

    public IAsyncEnumerable<PushDispatchWorkItem> ReadAllAsync(CancellationToken cancellationToken) =>
        _channel.Reader.ReadAllAsync(cancellationToken);
}
