using System.Buffers;
using AyCode.Core;
using AyCode.Core.Extensions;
using AyCode.Core.Tests.TestModels;
using AyCode.Services.Server.SignalRs;
using AyCode.Services.SignalRs;
using AyCode.Services.Tests.SignalRs;
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.AspNetCore.SignalR.Protocol;

namespace AyCode.Services.Server.Tests.SignalRs;

/// <summary>
/// Testable SignalR client that allows testing without real HubConnection.
/// Routes all messages through AyCodeBinaryHubProtocol with multi-segment splitting
/// to exercise the full serialization/deserialization pipeline.
/// </summary>
public class TestableSignalRClient2 : AcSignalRClientBase, IAcSignalRHubItemServer
{
    private HubConnectionState _connectionState = HubConnectionState.Connected;
    private readonly TestableSignalRHub2 _signalRHub;
    private readonly TestMultiSegmentProtocol _protocol;
    private readonly TestInvocationBinder _binder = new();

    /// <summary>
    /// Testable SignalR client that allows testing without real HubConnection.
    /// </summary>
    public TestableSignalRClient2(TestableSignalRHub2 signalRHub, TestLogger logger, BinaryProtocolMode mode = BinaryProtocolMode.Bytes) : base(logger)
    {
        MsDelay = 0;
        MsFirstDelay = 0;

        _signalRHub = signalRHub;
        _protocol = new TestMultiSegmentProtocol(mode);
    }

    #region Override virtual methods for testing

    protected override Task MessageReceived(int messageTag, SignalParams signalParams, object data)
    {
        throw new NotImplementedException();
    }

    protected override HubConnectionState GetConnectionState() => _connectionState;

    protected override bool IsConnected() => _connectionState == HubConnectionState.Connected;

    protected override Task StartConnectionInternal()
    {
        _connectionState = HubConnectionState.Connected;
        return Task.CompletedTask;
    }

    protected override Task StopConnectionInternal()
    {
        _connectionState = HubConnectionState.Disconnected;
        return Task.CompletedTask;
    }

    protected override ValueTask DisposeConnectionInternal() => ValueTask.CompletedTask;

    protected override Task SendToHubAsync(int messageTag, int? requestId, SignalParams signalParams, object? data)
    {
        // Protocol round-trip: serialize → multi-segment split → deserialize
        var invocation = new InvocationMessage(
            nameof(IAcSignalRHubClient.OnReceiveMessage),
            [messageTag, requestId, signalParams, data ?? Array.Empty<byte>()]);

        var bytes = _protocol.GetMessageBytesMultiSegment(invocation);
        var sequence = new ReadOnlySequence<byte>(bytes);
        if (!_protocol.TryParseMessage(ref sequence, _binder, out var parsed) || parsed is not InvocationMessage invMsg)
            throw new InvalidOperationException(
                $"Protocol round-trip failed. ByteCount={bytes.Length}, Parsed={parsed?.GetType().Name ?? "null"}, " +
                $"Tag={messageTag}, RequestId={requestId}, DataType={data?.GetType().Name ?? "null"}");

        var args = invMsg.Arguments;
        return _signalRHub.OnReceiveMessage(
            (int)args[0]!, (int?)args[1], (SignalParams)args[2]!, args[3]!);
    }
    #endregion

}


