using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using SlnMesnac.Config;
using SlnMesnac.TouchSocket.Entity;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using TouchSocket.Core;
using TouchSocket.Sockets;

#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* 版权所有 (c) 2024 WenJY 保留所有权利。
* CLR版本：4.0.30319.42000
* 机器名称：LAPTOP-E0N2L34V
* 命名空间：SlnMesnac.TouchSocket
* 唯一标识：496f8d2b-70e3-4a05-ae18-a9b0fcd06b82
*
* 创建者：WenJY
* 电子邮箱：wenjy@mesnac.com
* 创建时间：2024-03-27 21:58:35
* 版本：V1.0.0
* 描述：
*
*--------------------------------------------------------------------
* 修改人：
* 时间：
* 修改说明：
*
* 版本：V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
namespace SlnMesnac.TouchSocket
{
    public class TcpServer : BackgroundService
    {

        private ILogger<TcpServer> _logger;
        private readonly TcpService _service;
        private readonly AppConfig _appConfig;

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

        public delegate void RefreshClientInfo(TcpService tcpService);
        public event RefreshClientInfo? RefreshClientInfoEvent;

        public Action<String, bool> RefreshStateAction;

        public delegate void GetVisionData(TcpVisionEntity entity);

        /// <summary>
        /// 视觉系统反馈给上位机调度系统状态
        /// </summary>
        public event GetVisionData? VisionSysStateEvent;

        /// <summary>
        /// 视觉系统回复给上位机调度系统开始工作状态
        /// </summary>
        public event GetVisionData? VisionStartWorkEvent;

        /// <summary>
        /// 一次码垛完成，发送码垛结果
        /// </summary>
        public event GetVisionData? StackWorkDoneEvent;

        /// <summary>
        /// 视觉系统发送给机器人码垛位置定位结果
        /// </summary>
        public event GetVisionData? StackRobotLocationEvent;

        /// <summary>
        /// 人工异常处理完成并更新计数
        /// </summary>
        public event GetVisionData? ManualExceptionDealDoneEvent;

        private string ClientID = "";

        public TcpServer(ILogger<TcpServer> logger,TcpService tcpService, AppConfig appConfig)
        {
            _logger = logger;
            _service = tcpService;
            _appConfig = appConfig;
        }
                                                                                                                                                                                                                          
        protected override Task ExecuteAsync(CancellationToken stoppingToken)
        {
            Init(_appConfig.TCPVisionConfig);
            return Task.CompletedTask;
        }

        public void Init(string serverPort)
        {
            try
            {
                _service.Connecting = (client, e) => {
                    _logger.LogInformation($"客户端{client.IP}正在接入服务");
                    return EasyTask.CompletedTask;
                };
                _service.Connected = (client, e) => {
                    _logger.LogInformation($"客户端{client.IP}接入服务成功");
                    RefreshClientInfoEvent?.Invoke(_service);
                    RefreshStateAction?.Invoke(client.IP,true);
                    ClientID = client.Id;
                    return EasyTask.CompletedTask;
                };
                _service.Disconnected = (client, e) => {
                    _logger.LogInformation($"客户端{client.IP}断开连接");
                    RefreshStateAction?.Invoke(client.IP, false);
                    RefreshClientInfoEvent?.Invoke(_service);
                    return EasyTask.CompletedTask;
                };
                _service.Received = (client, e) =>
                {
                    //从客户端收到信息
                    var mes = Encoding.UTF8.GetString(e.ByteBlock.Buffer, 0, e.ByteBlock.Len);//注意：数据长度是byteBlock.Len
                    _logger.LogInformation($"客户端{client.IP}:"+ mes);
                    //区分一下指令类型，委托传参
                    
                    if (mes == "heartbeat")
                    {
                        RefreshStateAction?.Invoke(client.IP, true);
                    }
                    //var mes = Encoding.UTF8.GetString(e.ByteBlock.Buffer, 0, e.ByteBlock.Len);//注意：数据长度是byteBlock.Len

                    byte[] receivedBuffer = new byte[e.ByteBlock.Len];
                    Array.Copy(e.ByteBlock.Buffer, 0, receivedBuffer, 0, e.ByteBlock.Len);
                    //ReceivedClientBufferEvent?.Invoke(receivedBuffer);
                    DataClassify(BufferDataAnalysis.BufferRootAnalysis(receivedBuffer));

                    return EasyTask.CompletedTask;
                };

                _service.Setup(new TouchSocketConfig()//载入配置     
                    .SetListenIPHosts(new IPHost[] { new IPHost(serverPort) })
                    .ConfigureContainer(a =>//容器的配置顺序应该在最前面
                    {
                        a.AddConsoleLogger();
                    })
                    .ConfigurePlugins(a =>
                    {
                        //自定义插件
                    }));
                _service.Start();
                _logger.LogInformation($"TcpServer启动成功，监听端口：{serverPort}");
            }
            catch (Exception ex)
            {
                //throw new InvalidOperationException($"TcpServer启动异常：{ex.Message}");
                _logger.LogError($"TcpServer启动异常：{ex.Message}");
            }

        }

        /// <summary>
        /// 数据类型区分
        /// </summary>
        /// <param name="entity"></param>
        public void DataClassify(TcpVisionEntity entity)
        {
            if(entity == null)
            {
                _logger.LogError("数据格式校验错误！");
                return;
            }
            switch(entity.Command)
            {
                case 10: VisionSysStateEvent?.Invoke(entity); break;
                case 11: VisionStartWorkEvent?.Invoke(entity); break;
                case 12: StackWorkDoneEvent?.Invoke(entity); break;
                case 13: StackRobotLocationEvent?.Invoke(entity); break;
                case 14: ManualExceptionDealDoneEvent?.Invoke(entity); break;
                    default: _logger.LogInformation("未知命令字！"); return;
            }
        }

        ///// <summary>
        ///// 向所有客户端发送心跳
        ///// </summary>
        //public void SendHeartBeat()
        //{
        //    var clients = _service.SocketClients.GetClients();
        //    foreach (var item in clients)
        //    {
        //        _service.Send(item.Id,"heartbeat");
        //    }
        //}
    }
}
