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

namespace ColaFlow.Modules.Mcp.Application.EventHandlers;

/// <summary>
/// Event handler that sends SignalR notifications when a PendingChange is created
/// </summary>
public class PendingChangeCreatedNotificationHandler(
    IMcpNotificationService notificationService,
    IPendingChangeRepository repository,
    ILogger<PendingChangeCreatedNotificationHandler> logger)
    : INotificationHandler<PendingChangeCreatedEvent>
{
    private readonly IMcpNotificationService _notificationService = notificationService ?? throw new ArgumentNullException(nameof(notificationService));
    private readonly IPendingChangeRepository _repository = repository ?? throw new ArgumentNullException(nameof(repository));
    private readonly ILogger<PendingChangeCreatedNotificationHandler> _logger = logger ?? throw new ArgumentNullException(nameof(logger));

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

        try
        {
            // Get PendingChange for summary
            var pendingChange = await _repository.GetByIdAsync(notification.PendingChangeId, cancellationToken);
            if (pendingChange == null)
            {
                _logger.LogWarning(
                    "PendingChange not found - PendingChangeId={PendingChangeId}",
                    notification.PendingChangeId);
                return;
            }

            // Create notification DTO
            var notificationDto = new PendingChangeCreatedNotification
            {
                NotificationType = "PendingChangeCreated",
                PendingChangeId = notification.PendingChangeId,
                ToolName = notification.ToolName,
                EntityType = notification.EntityType,
                Operation = notification.Operation,
                Summary = pendingChange.GetSummary(),
                TenantId = notification.TenantId,
                Timestamp = DateTime.UtcNow
            };

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

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