using Bitfinex.Client.Websocket;
using Bitfinex.Client.Websocket.Client;
using Bitfinex.Client.Websocket.Requests;
using Bitfinex.Client.Websocket.Responses.Candles;
using Bitfinex.Client.Websocket.Utils;
using Bitfinex.Client.Websocket.Websockets;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using WebSocket.Clients;
using WebSocket.Interfaces;

namespace Knoks.CryptoExchanges.ExchangeClients
{
    class BitfinexExchange : IExchangeContainer
    {
        #region Members
        //private Dictionary<string, Candle> data = new Dictionary<string, Candle>();
        //private readonly int exchangeId;
        //private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
        //public UpdateData UpdateDataEvent { get; set; }

        private BitfinexWebsocket4Net socket;
        private BitfinexClient client;
        private int exchangeId;
        public IDictionary<string, string> ReplaceSymbols { get; set; }
        #endregion

        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="initExchangeId"></param>
        public BitfinexExchange(int initExchangeId) {
            this.exchangeId = initExchangeId;
        }

        public async Task InitClient(UpdateData updateData)
        {
            socket = new BitfinexWebsocket4Net();
            socket.Create(string.Empty);
            socket.Sign((s) => new ConsoleWebClient(
                updateData, 
                this.exchangeId, 
                (ss) =>
                {
                    return client = new BitfinexClient(ss);
                }, s));
            await socket.Connect();
        }

        public async Task RequestPairsData(List<Tuple<string, string>> pairs) {
            await socket.Connect(pairs.Select(x => $"{x.Item1}/{x.Item2}").ToArray());

            //data.Clear();
            //var url = BitfinexValues.ApiWebsocketUrl;
            //using (var communicator = new BitfinexWebsocketCommunicator(url))
            //{
            //    using (var client = new BitfinexWebsocketClient(communicator))
            //    {
            //        client.Streams.InfoStream.Subscribe(info =>
            //        {
            //            foreach (var item in pairs)
            //            {
            //                client.Send(new CandlesSubscribeRequest($"{item.Item1}/{item.Item2}", BitfinexTimeFrame.OneMinute));
            //            }
            //        });

            //        client.Streams.CandlesStream.Subscribe(candles =>
            //        {
            //            candles.CandleList.OrderBy(x => x.Mts).ToList().ForEach(x =>
            //            {
            //                this.data[candles.Pair] = x;
            //                this.UpdateDataEvent.Invoke(this.exchangeId, "Bitfinex", GetMarketOHLCVData());
            //            });
            //        });

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

        public async Task Reconnect() {
            //_cancellationTokenSource.Cancel();
            await socket.Close();
        }

        public async Task CloseConnection() {
            //_cancellationTokenSource.Cancel();
            await socket.Close();
        }
    }
}
