#if UNITY_WEBGL
using IoTCenter3D.UnityRpc;
using StreamJsonRpc;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
using UnityWebSocket.WebGL;


public class WebGLRpcClient : Rpc<WebGLRpcClient>
{
    WebSocket webSocket;
    public WebGLRpcClient(Configuration configuration, CancellationToken token) : base(configuration, token)
    {

    }
    public override async Task Initialize()
    {
        var initTask = base.Initialize();
        if (initTask.IsCompleted)
            return;
        string uri;
        if (Application.absoluteURL.StartsWith("https"))
        {
            Configuration.DefaultUseSSL = true;
        }
        else
        {
            Configuration.DefaultUseSSL = false;
        }

        if (Configuration.DefaultUseSSL) uri = $"wss://{Configuration.IpAdress}:{Configuration.Port}";
        else uri = $"ws://{Configuration.IpAdress}:{Configuration.Port}";

        using (webSocket = new WebSocket(uri))
        {
            webSocket.ConnectAsync();
            webSocket.OnOpen += WebSocket_OnOpen;
            webSocket.OnError += WebSocket_OnError;
            webSocket.OnClose += WebSocket_OnClose;
            var messageHandler = new WebGLMessageHandler(webSocket, new JsonMessageFormatter());
            Token.ThrowIfCancellationRequested();
            await UnityWebGLStartAsync(messageHandler,true);
        }
        FinishInitialize(true);
        await initTask;
    }

    private void WebSocket_OnClose(object sender, UnityWebSocket.CloseEventArgs e)
    {
        //throw new NotImplementedException();
        RaiseOnDisconnected(new JsonRpcDisconnectedEventArgs("close", DisconnectedReason.RemotePartyTerminated));
    }

    private void WebSocket_OnError(object sender, UnityWebSocket.ErrorEventArgs e)
    {
        FinishStop(false);
    }

    private void WebSocket_OnOpen(object sender, UnityWebSocket.OpenEventArgs e)
    {
        RaiseOnReady();
    }

    protected override void RaiseOnStart()
    {
        base.RaiseOnStart();
        if (!RemoteTypes.Any(x => x is IServerInformation) && !LocalTargets.Any(x => x is IServerInformation))
            RegisterRemoteTarget<IServerInformation>();
    }

    private bool disposed;

    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);

        if (disposed)
            return;
        if (disposing)
        {
            webSocket?.Dispose();
        }
        disposed = true;
    }
}
#endif