using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using WebSocket.Interfaces;

namespace WebSocket.Clients
{
    public class WebSocket4NetSocket : IWebSocket, IWebSocketForClient
    {
        #region Members
        protected WebSocket4Net.WebSocket Socket;
        protected Action OnTick = null;
        bool closedByUser = false;
        private int ExchangeId { get; set; }
        private UpdateData updateData { get; set; }
        public event EventHandler<Dictionary<string, object>> DataReceived1;
        #endregion

        public void OnDataReceived1(Dictionary<string, object> data) {
            DataReceived1(this, data);
        }

        public void DataChanged(string exchangeName, Dictionary<string, IMarketOHLCVData> data)
        {
            updateData.Invoke(this.ExchangeId, exchangeName, data);
        }

        public virtual void Create(string url)
        {
            Socket = new WebSocket4Net.WebSocket(url, null, WebSocket4Net.WebSocketVersion.Rfc6455);
        }

        public virtual async Task Close()
        {
            closedByUser = true;
            await Socket.CloseAsync();
        }

        public virtual async Task Connect()
        {
            await Socket.OpenAsync();
        }

        public void Sign(Func<IWebSocketForClient, IWebClient> fabric)
        {
            var client = fabric(this);
            if (Socket != null)
            {
                Socket.Closed += (obj, ev) => client.Closed(closedByUser, null);
                Socket.Opened += (obj, ev) => client.Connected();
                Socket.MessageReceived += (obj, ev) => client.Message(ev.Message);
                Socket.DataReceived += (obj, ev) => client.Data(ev.Data);
                Socket.Error += (obj, ev) => client.Error(ev.Exception);
            }
            DataReceived1 += (obj, obj1) => client.Data(obj1);
            OnTick = () => client.Tick();
        }

        void IWebSocketForClient.Ping()
        {
            //throw new NotImplementedException();
        }

        void IWebSocketForClient.Pong()
        {
            //throw new NotImplementedException();
        }

        public virtual async Task Connect(string[] pairs)
        {
            await Task.FromResult(true);
        }

        void IWebSocketForClient.Send(string message)
        {
            Socket.Send(message);
        }

        void IWebSocketForClient.Close()
        {
            Close().Wait();
        }
    }
}
