using CMSMicroservice.Application.Common.Interfaces;
using CMSMicroservice.WebApi.Hubs;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;

namespace CMSMicroservice.WebApi.Common.Services;

/// <summary>
/// Service for sending token-related notifications via SignalR
/// </summary>
public class TokenNotificationService : ITokenNotificationService
{
    private readonly IHubContext<TokenNotificationHub> _hubContext;
    private readonly ILogger<TokenNotificationService> _logger;

    public TokenNotificationService(
        IHubContext<TokenNotificationHub> hubContext,
        ILogger<TokenNotificationService> logger)
    {
        _hubContext = hubContext;
        _logger = logger;
    }

    /// <inheritdoc />
    public async Task NotifyTokenRevokedAsync(long userId, string reason)
    {
        try
        {
            _logger.LogInformation("Notifying token revoked for user {UserId}. Reason: {Reason}", userId, reason);
            
            await _hubContext.Clients.Group($"user_{userId}")
                .SendAsync("TokenRevoked", new TokenRevokedNotification
                {
                    UserId = userId,
                    Reason = reason,
                    Timestamp = DateTime.UtcNow
                });
            
            _logger.LogInformation("Token revoked notification sent for user {UserId}", userId);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to send token revoked notification for user {UserId}", userId);
        }
    }

    /// <inheritdoc />
    public async Task NotifyForceRefreshAsync(long userId)
    {
        try
        {
            _logger.LogInformation("Notifying force refresh for user {UserId}", userId);
            
            await _hubContext.Clients.Group($"user_{userId}")
                .SendAsync("ForceRefreshToken", new ForceRefreshNotification
                {
                    UserId = userId,
                    Timestamp = DateTime.UtcNow
                });
            
            _logger.LogInformation("Force refresh notification sent for user {UserId}", userId);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to send force refresh notification for user {UserId}", userId);
        }
    }

    /// <inheritdoc />
    public async Task BroadcastMessageAsync(string message)
    {
        try
        {
            _logger.LogInformation("Broadcasting message to all clients: {Message}", message);
            
            await _hubContext.Clients.All.SendAsync("BroadcastMessage", new BroadcastNotification
            {
                Message = message,
                Timestamp = DateTime.UtcNow
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to broadcast message");
        }
    }
}

/// <summary>
/// Notification payload for token revoked event
/// </summary>
public class TokenRevokedNotification
{
    public long UserId { get; set; }
    public string Reason { get; set; } = string.Empty;
    public DateTime Timestamp { get; set; }
}

/// <summary>
/// Notification payload for force refresh event
/// </summary>
public class ForceRefreshNotification
{
    public long UserId { get; set; }
    public DateTime Timestamp { get; set; }
}

/// <summary>
/// Notification payload for broadcast message
/// </summary>
public class BroadcastNotification
{
    public string Message { get; set; } = string.Empty;
    public DateTime Timestamp { get; set; }
}
