using System.Collections.Generic;
using System.Threading.Tasks;
using Assets.Scripts.Objects.Motherboards;
using EmbedIO.WebSockets;
using Swan;

namespace RemoteControl
{
    internal class SubscriptionModule: WebSocketModule
    {
        private HashSet<IWebSocketContext> _jsonSubscribers = new();
        public void SendUpdate(Message.Update update)
        {
            if (_jsonSubscribers.Count > 0)
            {
                var encoded = System.Text.Encoding.UTF8.GetBytes(update.ToJson());
                foreach (var webSocketContext in _jsonSubscribers)
                {
                    _ = SendAsync(webSocketContext, encoded);
                }
            }
            
        }
        
        public SubscriptionModule(string urlPath, bool enableConnectionWatchdog = true) : base(urlPath, enableConnectionWatchdog)
        {
            AddProtocols("json");
        }

        protected override Task OnMessageReceivedAsync(IWebSocketContext context, byte[] buffer, IWebSocketReceiveResult result)
        {
            return Task.CompletedTask;
        }

        protected override Task OnClientConnectedAsync(IWebSocketContext context)
        {
            _jsonSubscribers.Add(context);
            return base.OnClientConnectedAsync(context);
        }

        protected override Task OnClientDisconnectedAsync(IWebSocketContext context)
        {
            _jsonSubscribers.Remove(context);
            return base.OnClientDisconnectedAsync(context);
        }
    }

    namespace Message
    {
        public class Update
        {
           public List<Network> Networks { get; set; } = new();
        }

        public class Network
        {
            public long ReferenceId { get; set; }
            public List<string> Probes { get; set; } = new();
            
            public List<Device> Devices { get; set; } = new();
        }
        
        public class Device
        {
            public long ReferenceId { get; set; }
            public long NameHash{ get; set; }
            public string Name{ get; set; }
            public long PrefabHash{ get; set; }
            public string PrefabName{ get; set; }
            public Dictionary<LogicType, double> LogicValues { get; set; } = new();
            public List<Dictionary<LogicSlotType, double>> Slots { get; set; }= new();
        }
    }
}