using Microsoft.AspNetCore.Http.Connections;

namespace AyCode.Services.SignalRs;

/// <summary>
/// Options for a client-side SignalR <c>HubConnection</c>, designed to be bindable from
/// configuration (<c>appsettings.json</c>) via <c>services.Configure&lt;AcHubConnectionOptions&gt;(...)</c>.
/// Applied to an <c>IHubConnectionBuilder</c> via
/// <see cref="AcSignalRConnectionExtensions.AddAcConnection(Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder, AcHubConnectionOptions)"/>.
/// <para>
/// Most properties are nullable — when <c>null</c> the underlying SignalR / Microsoft default
/// is kept (the framework is non-opinionated). Resilience flags default to sensible modern values
/// (auto-reconnect on). Override in code or configuration.
/// </para>
/// <para>Precedence (low → high): property initializer → <c>services.Configure&lt;T&gt;(section)</c>
/// → <c>services.Configure&lt;T&gt;(action)</c>.</para>
/// </summary>
public sealed class AcHubConnectionOptions
{
    /// <summary>Target hub URL — absolute, including the hub path (e.g. <c>"https://host/fbHub"</c>).</summary>
    public string Url { get; set; } = "";

    // --- HttpConnectionOptions (applied via WithUrl) ---

    /// <summary>Transport(s) to negotiate. <c>null</c> → Microsoft default (<c>WebSockets | LongPolling | ServerSentEvents</c>).</summary>
    public HttpTransportType? Transports { get; set; }

    /// <summary>Max outbound transport buffer (bytes). <c>null</c> → Microsoft default (~64 KB).</summary>
    public int? TransportMaxBufferSize { get; set; }

    /// <summary>Max application-level send buffer (bytes). <c>null</c> → Microsoft default (~64 KB).</summary>
    public int? ApplicationMaxBufferSize { get; set; }

    /// <summary>WebSocket close handshake timeout. <c>null</c> → Microsoft default (5 s).</summary>
    public TimeSpan? CloseTimeout { get; set; }

    /// <summary>Skip negotiation (WebSockets-only setups). <c>null</c> → Microsoft default (<c>false</c>).</summary>
    public bool? SkipNegotiation { get; set; }

    // --- Connection-level ---

    /// <summary>Client-side keep-alive ping interval. <c>null</c> → SignalR default (15 s).</summary>
    public TimeSpan? KeepAliveInterval { get; set; }

    /// <summary>Server timeout (no-data threshold to declare the connection dead). <c>null</c> → SignalR default (30 s).</summary>
    public TimeSpan? ServerTimeout { get; set; }

    // --- Resilience (framework defaults — opinionated toward modern apps) ---

    /// <summary>Enable <c>WithAutomaticReconnect()</c>. Default: <c>true</c>.</summary>
    public bool UseAutomaticReconnect { get; set; } = true;

    /// <summary>Enable <c>WithStatefulReconnect()</c> (SignalR 8+). Default: <c>false</c> (opt-in — requires server support).</summary>
    public bool UseStatefulReconnect { get; set; } = false;
}
