using global::Knot.Contracts.Conversations.Application.Abstractions; using global::Knot.Contracts.Conversations.Domain; using global::Knot.Modules.Conversations.Infrastructure.SignalR; using global::Knot.Shared.Kernel; using MediatR; using Microsoft.AspNetCore.SignalR; using MessagingMessageRepository = Knot.Contracts.Messaging.Application.Abstractions.IMessageRepository; namespace Knot.Modules.Conversations.Application.Messages.Delete; public sealed record DeleteMessagesCommand( Guid ChatId, Guid UserId, List MessageIds, bool DeleteForAll) : ICommand; public sealed class DeleteMessagesCommandHandler : ICommandHandler { private readonly MessagingMessageRepository _messageRepository; private readonly IChatsUnitOfWork _unitOfWork; private readonly IHubContext _hubContext; public DeleteMessagesCommandHandler( MessagingMessageRepository messageRepository, IChatsUnitOfWork unitOfWork, IHubContext hubContext) { _messageRepository = messageRepository; _unitOfWork = unitOfWork; _hubContext = hubContext; } public async Task Handle(DeleteMessagesCommand request, CancellationToken cancellationToken) { foreach (var id in request.MessageIds) { var message = await _messageRepository.GetByIdAsync(id, cancellationToken); if (message is null || message.ChatId != request.ChatId) { continue; } if (request.DeleteForAll) { // Only message sender can delete for everyone if (message.SenderId == request.UserId) { message.Delete(); } else { // If not the sender, just delete for current user message.DeleteForUser(request.UserId); } } else { message.DeleteForUser(request.UserId); } await _messageRepository.UpdateAsync(message, cancellationToken); } // Notify all clients in the chat about the deletion await _hubContext.Clients.Group(request.ChatId.ToString()).SendAsync("messages_deleted", new { chatId = request.ChatId, messageIds = request.MessageIds, deleteForAll = request.DeleteForAll }); return global::Knot.Shared.Kernel.Result.Success(); } }