using ColaFlow.Modules.Mcp.Application.DTOs.Notifications;
using ColaFlow.Modules.Mcp.Application.Services;
using ColaFlow.Modules.Mcp.Domain.Events;
using MediatR;
using Microsoft.Extensions.Logging;

namespace ColaFlow.Modules.Mcp.Application.EventHandlers;

/// <summary>
/// Event handler that sends SignalR notifications when a PendingChange is approved
/// Runs in parallel with PendingChangeApprovedEventHandler (which executes the change)
/// </summary>
public class PendingChangeApprovedNotificationHandler(
    IMcpNotificationService notificationService,
    ILogger<PendingChangeApprovedNotificationHandler> logger)
    : INotificationHandler<PendingChangeApprovedEvent>
{
    private readonly IMcpNotificationService _notificationService = notificationService ?? throw new ArgumentNullException(nameof(notificationService));
    private readonly ILogger<PendingChangeApprovedNotificationHandler> _logger = logger ?? throw new ArgumentNullException(nameof(logger));

    public async Task Handle(PendingChangeApprovedEvent notification, CancellationToken cancellationToken)
    {
        _logger.LogInformation(
            "Handling PendingChangeApprovedEvent for notification - PendingChangeId={PendingChangeId}, EntityType={EntityType}",
            notification.PendingChangeId, notification.Diff.EntityType);

        try
        {
            // Create notification DTO
            var notificationDto = new PendingChangeApprovedNotification
            {
                NotificationType = "PendingChangeApproved",
                PendingChangeId = notification.PendingChangeId,
                ToolName = notification.ToolName,
                EntityType = notification.Diff.EntityType,
                Operation = notification.Diff.Operation,
                EntityId = notification.Diff.EntityId,
                ApprovedBy = notification.ApprovedBy,
                TenantId = notification.TenantId,
                Timestamp = DateTime.UtcNow
            };

            // Send notification via SignalR
            await _notificationService.NotifyPendingChangeApprovedAsync(notificationDto, cancellationToken);

            _logger.LogInformation(
                "PendingChangeApproved notification sent successfully - PendingChangeId={PendingChangeId}",
                notification.PendingChangeId);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex,
                "Failed to send PendingChangeApproved notification - PendingChangeId={PendingChangeId}",
                notification.PendingChangeId);
            // Don't rethrow - notification failure shouldn't break the main flow
        }
    }
}
