using Knot.Contracts.Messaging.Application.Abstractions;
using Knot.Contracts.Messaging.Domain;
using Knot.Contracts.Conversations.Application.Abstractions;
using Knot.Contracts.Conversations.Domain;
using Knot.Modules.Conversations.Infrastructure.SignalR;
using Knot.Shared.Kernel;
using MediatR;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;

namespace Knot.Modules.Conversations.Application.Messages.React;

public sealed record RemoveReactionCommand(
    Guid MessageId,
    Guid UserId,
    string Emoji,
    Guid ChatId) : ICommand;

public sealed class RemoveReactionCommandHandler : ICommandHandler<RemoveReactionCommand>
{
    private readonly IMessageReactionRepository _reactionRepository;
    private readonly IChatsUnitOfWork _unitOfWork;
    private readonly IHubContext<ChatHub> _hubContext;
    private readonly ILogger<RemoveReactionCommandHandler> _logger;

    public RemoveReactionCommandHandler(
        IMessageReactionRepository reactionRepository,
        IChatsUnitOfWork unitOfWork,
        IHubContext<ChatHub> hubContext,
        ILogger<RemoveReactionCommandHandler> logger)
    {
        _reactionRepository = reactionRepository;
        _unitOfWork = unitOfWork;
        _hubContext = hubContext;
        _logger = logger;
    }

    public async Task<Result> Handle(RemoveReactionCommand request, CancellationToken cancellationToken)
    {
        _logger.LogInformation("RemoveReaction: MessageId={MessageId}, UserId={UserId}, Emoji={Emoji}, ChatId={ChatId}",
            request.MessageId, request.UserId, request.Emoji, request.ChatId);

        await _reactionRepository.RemoveAsync(
            request.MessageId,
            request.UserId,
            request.Emoji,
            cancellationToken);

        await _unitOfWork.SaveChangesAsync(cancellationToken);

        _logger.LogInformation("RemoveReaction: Reaction removed from database");

        await _hubContext.Clients.Group(request.ChatId.ToString()).SendAsync("reaction_removed", new
        {
            messageId = request.MessageId,
            chatId = request.ChatId,
            userId = request.UserId,
            emoji = request.Emoji
        });

        _logger.LogInformation("RemoveReaction: reaction_removed sent successfully");

        return Result.Success();
    }
}


