using Admin.Core.Common;

using log4net;
using System.Text;
using System.Threading;
using TouchSocket.Core;
using TouchSocket.Sockets;

namespace Admin.Core.Socket
{
    public class TouchSocketService : ITouchSocketService
    {
        private static readonly log4net.ILog log = LogManager.GetLogger(typeof(TouchSocketService));

        /// <summary>
        /// 刷新扫码器状态
        /// </summary>
        /// <param name="materialCodeStr"></param>
        /// <param name="ip"></param>
        public delegate void RefreshState(string ip, bool flag);
        public static event RefreshState RefreshStateEvent;

        /// <summary>
        /// NoRead业务事件处理
        /// </summary>
        /// <param name="materialCodeStr"></param>
        /// <param name="ip"></param>
        public delegate void NoReadReceive(string ip);
        public static event NoReadReceive NoReadReceiveEvent;

        /// <summary>
        /// 扫码业务触发事件
        /// </summary>
        /// <param name="Code1"></param>
        public delegate void ReceiveCodeDelegate(string IP,string code);
        public static event ReceiveCodeDelegate? ReceiveCodeDelegateEvent;

        /// <summary>
        /// 接收客户端指令委托
        /// </summary>
        public delegate void ReceivedClientBuffer(SocketClient client, byte[] buffer);
        public static event ReceivedClientBuffer? ReceivedClientBufferEvent;

        /// <summary>
        /// 连接信息
        /// </summary>
        /// <param name="tcpService"></param>
        public delegate void RefreshClientInfo(TcpService tcpService);
        public static event RefreshClientInfo? RefreshClientInfoEvent;

        TcpService service;
        
        #region 初始化构造函数
        public TouchSocketService()
        {

        }
        #endregion

        #region Socket 初始化
        public Task<MessageModel<string>> AddTouchSocketAsync()
        {
            MessageModel<string> messageModel = new MessageModel<string>();

            service = new TcpService();
            service.Connecting = (client, e) => { 
                client.Logger.Info($"{client.IP}:{client.Port} 客户端正在连接...");
                return EasyTask.CompletedTask;
            };//有客户端正在连接
            service.Connected = (client, e) => { client.Logger.Info($"{client.IP}:{client.Port} 客户端连接成功!目前客户端连接数{service.Count}");

                SetProdStoreClientId(client);

                return EasyTask.CompletedTask;
            };//有客户端成功连接
            service.Disconnected += (client, e) => { //有客户端断开连接
                client.Logger.Info($"{client.IP}:{client.Port}客户端断开!"); 
                RefreshStateEvent?.Invoke(client.IP, false);
                RefreshClientInfoEvent?.Invoke(service);
                return EasyTask.CompletedTask;
            };
            service.Received = (client, e) =>
            {
                #region 原始Buffer
                byte[] receivedBuffer = new byte[e.ByteBlock.Len];
                Array.Copy(e.ByteBlock.Buffer, 0, receivedBuffer, 0, e.ByteBlock.Len);
                ReceivedClientBufferEvent?.Invoke(client, receivedBuffer);
                #endregion
                try
                {
                    var mes = Encoding.UTF8.GetString(e.ByteBlock.Buffer, 0, e.ByteBlock.Len);//注意:数据长度是byteBlock.Len
                    //心跳包
                    if (mes== "heartbeat")
                    {
                        //扫码器心跳连接
                        client.Logger.Info($"已从{client.IP}:{client.Port}》接收到心跳信息:{mes}");
                        RefreshStateEvent?.Invoke(client.IP, true);
                    }
                    else if (mes == "NoRead")
                    {
                        NoReadReceiveEvent?.Invoke(client.IP);
                        client.Logger.Info($"未从{client.IP}:{client.Port}》接收到二维码信息{mes}");

                    }
                    else
                    {
                        ReceiveCodeDelegateEvent?.Invoke(client.IP,mes);
                        client.Logger.Info($"已从{client.IP}:{client.Port}》接收到信息:{mes}");
                    }

                     
                }
                catch (Exception ex)
                {
                    client.Logger.Error($"异常:{ex.Message}");
                }
                return EasyTask.CompletedTask;
            };


            //        service.Setup(new TouchSocketConfig()//载入配置     
            //.SetListenIPHosts(new IPHost[] { new IPHost($"0.0.0.0:5000") })
            //.ConfigureContainer(a =>//容器的配置顺序应该在最前面
            //{
            //    a.AddConsoleLogger();
            //})
            //.ConfigurePlugins(a =>
            //{
            //    //自定义插件
            //}));

            service.Setup(new TouchSocketConfig()//载入配置
                    .SetListenIPHosts(new IPHost[] { new IPHost($"0.0.0.0:5000") })//可同时监听两个地址
                                                                                   //  .SetDataHandlingAdapter(() => { return new NormalDataHandlingAdapter(); })//配置适配器
                    .SetMaxCount(10000)
                    //.SetThreadCount(1000)
                    //.SetCacheTimeoutEnable(false)
                    .ConfigureContainer(a =>
                    {
                        a.AddConsoleLogger();
                    })
                    .ConfigurePlugins(a =>
                    {
                        a.UseCheckClear();
                    }));
            service.Start();//启动

            service.Logger.Info("服务器成功启动");
            messageModel.success = true;
            messageModel.msg = "OK";
            return Task.FromResult(messageModel);
        }

        #endregion

        /// <summary>
        /// 设置成品库扫码器的Id,将客户端ID设置为货道区域
        /// </summary>
        /// <param name="client"></param>
        private void SetProdStoreClientId(SocketClient client)
        {
            if (client.IP == "10.10.92.230")
            {
                client.ResetId("A");
            }
            else if (client.IP == "10.10.92.231")
            {
                client.ResetId("B");
            }
            RefreshClientInfoEvent?.Invoke(service);
        }

    }
}