using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;

namespace PowderCoating.Web.Hubs;

/// <summary>
/// SignalR hub that delivers real-time notifications to authenticated users.
/// Each user is placed into a company-scoped SignalR group ("company-{companyId}") on connect so
/// that server-side code can broadcast to an entire tenant without iterating individual connections.
/// SuperAdmin users are also placed in the "superadmin" group for platform-wide alerts.
/// </summary>
[Authorize]
public class NotificationHub : Hub
{
    private readonly ILogger<NotificationHub> _logger;

    /// <summary>
    /// Initializes a new instance of <see cref="NotificationHub"/> with the required logger.
    /// </summary>
    public NotificationHub(ILogger<NotificationHub> logger)
    {
        _logger = logger;
    }

    /// <summary>
    /// Called by the SignalR framework when a client establishes a connection.
    /// Reads the CompanyId claim from the authenticated user and adds the connection to the
    /// corresponding company group. SuperAdmins are additionally added to the "superadmin" group.
    /// Errors are caught and logged rather than re-thrown so that a group-join failure does not
    /// abort the connection handshake for the client.
    /// </summary>
    public override async Task OnConnectedAsync()
    {
        try
        {
            var companyId = Context.User?.FindFirst("CompanyId")?.Value;
            if (!string.IsNullOrEmpty(companyId))
                await Groups.AddToGroupAsync(Context.ConnectionId, $"company-{companyId}");

            if (Context.User?.IsInRole("SuperAdmin") == true)
                await Groups.AddToGroupAsync(Context.ConnectionId, "superadmin");

            await base.OnConnectedAsync();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error in NotificationHub.OnConnectedAsync for connection {ConnectionId}", Context.ConnectionId);
        }
    }

    /// <summary>
    /// Called by the SignalR framework when a client disconnects, either cleanly or due to an error.
    /// Unexpected disconnects (non-null exception) are logged at Warning level so they appear in
    /// monitoring without spamming the error log during normal browser refreshes.
    /// </summary>
    public override async Task OnDisconnectedAsync(Exception? exception)
    {
        if (exception != null)
            _logger.LogWarning(exception, "NotificationHub client disconnected with error: {ConnectionId}", Context.ConnectionId);

        await base.OnDisconnectedAsync(exception);
    }
}
