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

namespace PowderCoating.Web.Hubs;

/// <summary>
/// SignalR hub that delivers "StartIntake" push events to the front-desk tablet.
/// Deliberately [AllowAnonymous] — the tablet runs without a logged-in user.
/// Security is enforced at the kiosk route level via the KioskActivationToken cookie.
///
/// On connect the tablet passes ?companyId=N in the hub URL query string; this hub
/// places that connection in the company-scoped group "kiosk-{companyId}" so that
/// KioskController.StartSession can push to exactly that company's tablet.
/// </summary>
[AllowAnonymous]
public class KioskHub : Hub
{
    private readonly ILogger<KioskHub> _logger;

    /// <summary>Initialises the hub with the required logger.</summary>
    public KioskHub(ILogger<KioskHub> logger)
    {
        _logger = logger;
    }

    /// <summary>
    /// Joins the connection to the company-scoped kiosk group on connect.
    /// companyId is read from the ?companyId query param embedded in the hub URL by the Welcome view.
    /// </summary>
    public override async Task OnConnectedAsync()
    {
        try
        {
            var companyId = Context.GetHttpContext()?.Request.Query["companyId"].FirstOrDefault();
            if (!string.IsNullOrEmpty(companyId))
                await Groups.AddToGroupAsync(Context.ConnectionId, $"kiosk-{companyId}");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error in KioskHub.OnConnectedAsync for connection {ConnectionId}", Context.ConnectionId);
        }

        await base.OnConnectedAsync();
    }

    /// <summary>Logs unexpected disconnects (e.g. tablet going to sleep).</summary>
    public override async Task OnDisconnectedAsync(Exception? exception)
    {
        if (exception != null)
            _logger.LogWarning(exception, "KioskHub client disconnected with error: {ConnectionId}", Context.ConnectionId);

        await base.OnDisconnectedAsync(exception);
    }
}
