using System;
using System.Collections.Generic;
using System.Text;

namespace WebSocket.Interfaces
{
    public class ConsoleWebClient : IWebClient
    {
        private IWebClient client;

        public ConsoleWebClient(UpdateData updateData, int exchangeId, Func<IWebSocketForClient, IWebClient> fabric, IWebSocketForClient server)
        {
            client = fabric(new WebSocketForClient(updateData, exchangeId, server));
        }

        internal class WebSocketForClient : IWebSocketForClient
        {
            private IWebSocketForClient client;
            private UpdateData updateData { get; set; }
            private int ExchangeId { get; set; }

            public WebSocketForClient(UpdateData updateData, int exchangeId, IWebSocketForClient client)
            {
                this.client = client;
                this.updateData = updateData;
                this.ExchangeId = exchangeId;
            }

            public void Close()
            {
                client.Close();
                Console.WriteLine("Called Close");
            }

            public void Ping()
            {
                client.Ping();
                Console.WriteLine("Sent ping");
            }
            public void Pong()
            {
                client.Pong();
                Console.WriteLine("Sent pong");
            }
            public void Send(string message)
            {
                client.Send(message);
                //Console.WriteLine("Sent: " + message);
            }
            public void DataChanged(string exchangeName, Dictionary<string, IMarketOHLCVData> data)
            {
                updateData.Invoke(this.ExchangeId, exchangeName, data);
            }
        }

        public void Closed(bool byUser, string reason)
        {
            Console.WriteLine("Closed " + (byUser ? "by request" : reason != null ? ("by " + reason) : ""));
            client.Closed(byUser, reason);
        }

        public void Connected()
        {
            Console.WriteLine("Connected");
            client.Connected();
        }

        public void Data(byte[] data)
        {
            //Console.WriteLine("Received: " + data);
            client.Data(data);
        }

        public void Data(Dictionary<string, object> data)
        {
            client.Data(data);
        }

        public void Message(string message)
        {
            //Console.WriteLine("Received: " + message);
            client.Message(message);
        }

        //public void ReceivedPing(string data)
        //{
        //    Console.WriteLine("Ping " + data);
        //    client.ReceivedPing(data);
        //}

        //public void ReceivedPong(string data)
        //{
        //    Console.WriteLine("Pong " + data);
        //    client.ReceivedPong(data);
        //}
        public void Tick()
        {
            Console.WriteLine("Tick");
            client.Tick();
        }

        public void Error(Exception ex)
        {
            Console.WriteLine("Exception: " + ex?.Message);
            client.Error(ex);
        }

        public void Error(string reason)
        {
            Console.WriteLine("Error: " + reason);
            client.Error(reason);
        }

        public void SendFailed(string data, Exception ex)
        {
            Console.WriteLine("Send Failed: " + data + "" + ex?.Message);
            client.SendFailed(data, ex);
        }

        public Dictionary<string, IMarketOHLCVData> GetMarketOHLCVData(Dictionary<string, object> data)
        {
            throw new NotImplementedException();
        }
    }
}
