using System;
using System.Threading;
using System.Threading.Tasks;
using RudderSdk.Core.Abstractions;

namespace RudderSdk.Unity
{
  internal sealed class UnityRealtimeTransportFactory : IRealtimeTransportFactory
  {
    public IRealtimeTransport Create()
    {
#if UNITY_WEBGL && !UNITY_EDITOR
      return new UnityRealtimeTransport(new JsWebSocketAdapter());
#else
      return new UnityRealtimeTransport(new NativeWebSocketAdapter());
#endif
    }
  }

  internal sealed class UnityRealtimeTransport : IRealtimeTransport
  {
    private readonly IWebSocketAdapter _adapter;

    public UnityRealtimeTransport(IWebSocketAdapter adapter)
    {
      _adapter = adapter;
      _adapter.Closed += () => Closed?.Invoke();
      _adapter.Received += data => Received?.Invoke(data);
      _adapter.ReceivedError += ex => Error?.Invoke(ex);
    }

    public event Action Closed;
    public event Action<ArraySegment<byte>> Received;
    public event Action<Exception> Error;

    public bool IsConnected => _adapter.IsConnected;

    public Task ConnectAsync(Uri uri, TimeSpan timeout, CancellationToken cancellationToken = default)
      => _adapter.ConnectAsync(uri, (int)Math.Ceiling(timeout.TotalSeconds), cancellationToken);

    public Task SendAsync(ArraySegment<byte> data, CancellationToken cancellationToken = default)
      => _adapter.SendAsync(data, cancellationToken);

    public Task CloseAsync(CancellationToken cancellationToken = default)
      => _adapter.CloseAsync();

    public void Update(float deltaTime)
    {
    }
  }
}
