using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Bitfinex.Client.Websocket;
using Bitfinex.Client.Websocket.Websockets;
using Bitfinex.Client.Websocket.Client;
using Bitfinex.Client.Websocket.Requests;
using Bitfinex.Client.Websocket.Utils;
using System.Linq;
using System.Threading;

namespace WebSocket.Clients
{
    public class BitfinexWebsocket4Net : WebSocket4NetSocket
    {
        #region Members
        private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
        //private Timer Timer;
        //private DateTime? LastCall;
        private DateTime? CreateTime;
        #endregion

        /// <summary>
        /// ctor
        /// </summary>
        public BitfinexWebsocket4Net() {
        }

        public override void Create(string url)
        {
            //this.ExchangeId = exchangeId;
            //this.updateData = updateDate;
            //Socket.MessageReceived += Socket_MessageReceived;
            CreateTime = DateTime.Now;
        }

        //private void Socket_MessageReceived(object sender, WebSocket4Net.MessageReceivedEventArgs e)
        //{
        //    LastCall = DateTime.Now;
        //}

        public async override Task Connect()
        {
            await Task.CompletedTask;
        }

        public async override Task Connect(string[] pairs) {
            using (var communicator = new BitfinexWebsocketCommunicator(BitfinexValues.ApiWebsocketUrl))
            {
                using (var client = new BitfinexWebsocketClient(communicator))
                {
                    client.Streams.InfoStream.Subscribe(info =>
                    {
                        foreach (var item in pairs)
                        {
                            client.Send(new CandlesSubscribeRequest(item, BitfinexTimeFrame.OneMinute));
                        }
                    });

                    client.Streams.CandlesStream.Subscribe(candles =>
                    {
                        candles.CandleList.OrderBy(x => x.Mts).ToList().ForEach(x =>
                        {
                            OnDataReceived1(new Dictionary<string, object> {  { candles.Pair, x } });
                        });
                    });

                    await communicator.Start();
                    await Task.Run(() => CheckReconnect(_cancellationTokenSource.Token), _cancellationTokenSource.Token);
                }
            }
        }

        private async Task CheckReconnect(CancellationToken token)
        {
            do
            {
                await Task.CompletedTask;
            } while (!token.WaitHandle.WaitOne(TimeSpan.FromSeconds(1)));
        }

        public override Task Close()
        {
            _cancellationTokenSource.Cancel();
            return Task.CompletedTask;
        }
    }
}
