using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
using System.IO;
using Bittrex.Net;
using Bittrex.Net.Objects;
using CryptoExchange.Net.Authentication;
using CryptoExchange.Net.Logging;

namespace WebSocket.Clients
{
    public class BittrexWebsocket4Net : WebSocket4NetSocket
    {
        #region Members
        private BittrexSocketClient socketClient;
        private string[] subscribedPairs;
        //private Timer Timer;
        //private DateTime? LastCall;
        private DateTime? CreateTime;
        #endregion

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

        public override void Create(string url)
        {
            //Socket.EnableAutoSendPing = false;
            //Socket.MessageReceived += Socket_MessageReceived;
            CreateTime = DateTime.Now;

            BittrexClient.SetDefaultOptions(new BittrexClientOptions()
            {
                ApiCredentials = new ApiCredentials("d95322fdc5c94df7afa234d184195fe8", "5111332bbeed417883e912f8c288f596"),
                LogVerbosity = LogVerbosity.Info,
                LogWriters = new List<TextWriter>() { Console.Out }
            });
            socketClient = new BittrexSocketClient();
        }

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

        public async override Task Connect()
        {
            await socketClient.SubscribeToMarketSummariesUpdateAsync(summaries =>
            {
                if (this.subscribedPairs != null && this.subscribedPairs.Count() > 0)
                {
                    foreach (var item in summaries)
                    {
                        if (this.subscribedPairs.Contains(item.MarketName))
                        {
                            //data[item.MarketName] = item;
                            OnDataReceived1(new Dictionary<string, object> { { item.MarketName, item } });
                        }
                    }
                }
                //var item = summaries.SingleOrDefault(s => s.MarketName == "BTC-ETH");
                //Console.WriteLine($"BTC-ETH: {summaries.SingleOrDefault(s => s.MarketName == "BTC-ETH")?.Last}");
            });

            //await base.Connect();
            //Timer = new Timer((obj) => SpecialTick(), null, 16000, 16000);
            //BittrexClient.SetDefaultOptions(new BittrexClientOptions()
            //{
            //    ApiCredentials = new ApiCredentials("d95322fdc5c94df7afa234d184195fe8", "5111332bbeed417883e912f8c288f596"),
            //    LogVerbosity = LogVerbosity.Info,
            //    LogWriters = new List<TextWriter>() { Console.Out }
            //});

            //// Websocket
            //var socketClient = new BittrexSocketClient();
            //var subscription = await socketClient.SubscribeToMarketSummariesUpdateAsync(summaries =>
            //{
            //    foreach (var item in summaries) {
            //        data[item.MarketName] = item;
            //    }
            //    //var item = summaries.SingleOrDefault(s => s.MarketName == "BTC-ETH");
                
            //    //Console.WriteLine($"BTC-ETH: {summaries.SingleOrDefault(s => s.MarketName == "BTC-ETH")?.Last}");
            //});

        }

        public override Task Connect(string[] pairs) {
            //data.Clear();
            this.subscribedPairs = pairs;
            return Task.CompletedTask;
        }
        
        //private void SpecialTick()
        //{
        //    DateTime? lastCall = new List<DateTime?>() { Socket.LastActiveTime, LastCall, CreateTime }.Where(it => it.HasValue && it != DateTime.MinValue).Max();
        //    if (lastCall == null || DateTime.Now - lastCall > TimeSpan.FromSeconds(15))//15 - by auto tick
        //    {
        //        OnTick();
        //    }
        //}

        public override Task Close()
        {
            socketClient.UnsubscribeAllStreams();
            return Task.FromResult(true); // base.Close();
        }
    }
}
