using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;

namespace ZB.MOM.WW.MxGateway.Server.Dashboard.Hubs;

/// <summary>
/// SignalR hub that pushes a fresh <see cref="DashboardSnapshot"/> on every
/// snapshot refresh. New connections receive the current snapshot
/// immediately via <see cref="OnConnectedAsync"/>; subsequent refreshes are
/// broadcast by <see cref="DashboardSnapshotPublisher"/>.
/// </summary>
/// <remarks>
/// Connections are counted into <see cref="DashboardSnapshotHubConnectionCounter"/>
/// so <see cref="DashboardSnapshotPublisher"/> can stop building and broadcasting
/// snapshots while nobody is watching.
/// </remarks>
[Authorize(Policy = DashboardAuthenticationDefaults.HubClientsPolicy)]
public sealed class DashboardSnapshotHub(
    IDashboardSnapshotService snapshotService,
    DashboardSnapshotHubConnectionCounter connectionCounter) : Hub
{
    /// <summary>Method name used to push snapshot updates to clients.</summary>
    public const string SnapshotMessage = "SnapshotUpdated";

    /// <inheritdoc />
    public override async Task OnConnectedAsync()
    {
        // Count the viewer before seeding it, so the publisher resumes its tick
        // no later than the first snapshot this connection renders.
        connectionCounter.Increment();
        await Clients.Caller.SendAsync(SnapshotMessage, snapshotService.GetSnapshot()).ConfigureAwait(false);
        await base.OnConnectedAsync().ConfigureAwait(false);
    }

    /// <inheritdoc />
    public override async Task OnDisconnectedAsync(Exception? exception)
    {
        connectionCounter.Decrement();
        await base.OnDisconnectedAsync(exception).ConfigureAwait(false);
    }
}
