using BinanceExchange.API.Client;
using BinanceExchange.API.Enums;
using BinanceExchange.API.Models.Request;
using BinanceExchange.API.Models.Response;
using BinanceExchange.API.Models.WebSocket;
using BinanceExchange.API.Websockets;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace SignalsTest
{


    public class CoinWatch
    {
        public bool kickstarted = false;
        public string pair;
        public int index;
        public KlineInterval interval = KlineInterval.FifteenMinutes;
        public List<KlineCandleStickResponse> candles=new List<KlineCandleStickResponse>();
        public List<TAReport> reports = new List<TAReport>();
        public event EventHandler<BinanceTradeData> PriceUpdated;
        bool usingCache;
        public CoinWatch(string pair,int index, KlineInterval _interval = KlineInterval.FifteenMinutes , bool useCache=false)
        {
            this.pair = pair;
            this.index = index;
            interval = _interval;
            usingCache = useCache;
            Init();
        }

        void Init()
        {
            if(usingCache){
                if(File.Exists(AppDomain.CurrentDomain.BaseDirectory+"/"+pair+".txt")){
                    try{
                        
                    }catch{

                    }
                }
            }
            InitLivestream();
            KeepUpdatingCandles();
         // TestCallbacks();
        }

        async void TestCallbacks()
        {
            while (true)
            {
                await Task.Delay(1000);
                PriceUpdated?.Invoke(this, new BinanceTradeData() { BestAskPrice=0 });
            }
        }

        async Task UpdateCandles()
        {
            GetKlinesCandlesticksRequest req = new GetKlinesCandlesticksRequest();
            req.Interval = interval;
            req.Symbol = pair;
            req.EndTime = DateTime.Now;
            req.Limit = 100;

            candles = await Brian.Client.GetKlinesCandlesticks(req);
            Console.WriteLine($"Done gettings Kandles for {req.Symbol}, {candles.Count} kandles retreived");
            kickstarted = true;
            Analyze(req.Symbol);
        }

        async void Analyze(string symbol){
            int[] mas = new int[] { 7, 12, 25 };
            reports = new List<TAReport>();
            decimal max = 0;
            decimal min = 100000000;
            decimal maxVol = 0;


            for(int i=0; i < candles.Count; i++){

                TAReport report = TAReport.Generate(pair, Utils.GetMinutesForInterval(interval) ,candles, i,reports);
                if(candles[i].Close > max){
                    max = candles[i].Close;
                }
                if(candles[i].Close < min){
                    min = candles[i].Close;
                }

                if(candles[i].Volume > maxVol){
                    maxVol = candles[i].Volume;
                }
                reports.Add(report);

            }
            Console.WriteLine($"Drawing chart for {reports.Count} candles, Coin: {symbol}, ceil:{max}, floor:{min}");
            
            // Console.WriteLine("Picasso did his job");
            // Console.WriteLine(reports[reports.Count-1].toJson());
            bool isStSwitch=false;

            for(int i=0; i< 2; i++){
                bool _isStSwitch = reports[reports.Count-1-i].STUp != reports[reports.Count-i-2].STUp;

                if(_isStSwitch){
                    isStSwitch=true;
                    break;
                }
            }
            if(isStSwitch){
                Picasso.DrawChart(reports, max ,min, maxVol, symbol);
                await Messenger.instance.SendLastChart(filename:symbol);
                await Messenger.instance.SendMessage($"`{symbol}` switched the SuperTrend lines. Current price: {reports[reports.Count-1].Close}");
            }
            if(reports[reports.Count-1].TGOR){
                Picasso.DrawChart(reports, max ,min, maxVol, symbol);
                await Messenger.instance.SendLastChart(filename:symbol);
                await Messenger.instance.SendMessage($"`{symbol}` dipped in a bull run. Current price: {reports[reports.Count-1].Close}");
            }
        }

        async void KeepUpdatingCandles()
        {
            int delay = (index * 1000);
            await Task.Delay(delay);

            UpdateCandles();
            while(true)
            {
                await Task.Delay(60000 + delay);
                Console.WriteLine($"Loop call, ({index}) , {DateTime.Now.Minute} = {DateTime.Now.Minute % Utils.GetMinutesForInterval(interval)} ");
                if (DateTime.Now.Minute % Utils.GetMinutesForInterval(interval) == 0) { UpdateCandles(); }
            }
        }

        void InitLivestream()
        {
            var manualWebsocket = new InstanceBinanceWebSocketClient(Brian.Client);
            var socketId = manualWebsocket.ConnectToIndividualSymbolTickerWebSocket(pair, data =>
            {
                if(candles.Count > 0){
                    candles[candles.Count - 1].Close = data.BestAskPrice;
                }
            });
        }
    }
}
