using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Serilog;
using Serilog.Core;
using SlnMesnac.Config;
using SlnMesnac.TouchSocket.Entity;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
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
    {

        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, string id);

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

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

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

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

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

        private string TestClientID = "";

        public TcpServer(ILogger<TcpServer> logger, TcpService tcpService, AppConfig appConfig)
        {
            _logger = logger;
            _service = tcpService;
            _appConfig = appConfig;

            ReceiveStackWorkDoneEvent += StackResultSend;
            ReceiveManualExceptionDealDoneEvent += ManualExceptionDealDone;
        }

        public void Init(int 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);
                    client.ResetId(client.Port.ToString());
                    TestClientID = client.Port.ToString();
                    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);
                    }



                    byte[] receivedBuffer = new byte[e.ByteBlock.Len];
                    Array.Copy(e.ByteBlock.Buffer, 0, receivedBuffer, 0, e.ByteBlock.Len);
                    DataClassify(BufferDataAnalysis.BufferRootAnalysis(receivedBuffer), client.Id);

                    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}");
            }

        }

        //private void Test()
        //{
        //    try
        //    {
        //        Task.Run(() =>
        //        {
        //            // 设置计时器
        //            Stopwatch stopwatch = new Stopwatch();
        //            stopwatch.Start();
        //            ISocketClient client = _service.SocketClients.GetClients().FirstOrDefault(x => x.IP == "127.0.0.1");
        //            if (client != null)
        //            {
        //                Thread.Sleep(4000);
        //                _service.Send(client.Id, new byte[0x01]);
   
        //            }
        //            // 检查是否超过两秒
        //            if (stopwatch.ElapsedMilliseconds > 2000)
        //            {
        //                _logger.LogError("超时");
        //            }
        //            Thread.Sleep(100);
        //        });
        //    }
        //    catch (Exception ex)
        //    {

        //    }
        //}


        /// <summary>
        /// 接收数据类型区分
        /// </summary>
        /// <param name="entity"></param>
        public void DataClassify(TcpVisionEntity entity, string id)
        {
            if (entity == null)
            {
                _logger.LogError("数据格式校验错误！");
                return;
            }
            switch (entity.Command)
            {
                case 0x10: ReceiveVisionSysStateEvent?.Invoke(entity, id); break;
                case 0x11: ReceiveVisionStartWorkEvent?.Invoke(entity, id); break;
                case 0x12: ReceiveStackWorkDoneEvent?.Invoke(entity, id); break;
                case 0x13: ReceiveStackRobotLocationEvent?.Invoke(entity, id); break;
                case 0x14: ReceiveManualExceptionDealDoneEvent?.Invoke(entity, id); break;
                default: _logger.LogInformation("未知命令字！"); return;
            }
        }

        #region 数据发送

        /// <summary>
        /// 上位机调度系统请求视觉系统状态
        /// </summary>
        /// <param name="SN">SN码</param>
        /// <param name="id">客户端ID</param>
        public void SendRequestVisionSysState(byte[] SN, string id)
        {
            try
            {
                _service.SendAsync(id, BufferDataAnalysis.DataCombine(SN, 0x00, new byte[0]));
            }
            catch (Exception e)
            {
                _logger.LogError("Error:" + e);
            }
        }

        /// <summary>
        /// AMR就绪，请求视觉开始工作
        /// </summary>
        /// <param name="SN">SN码</param>
        /// <param name="data">数据体</param>
        /// <param name="id">客户端ID</param>
        public void SendAMRRequestVisionStartWork(byte[] SN, byte[] data, string id)
        {
            try
            {
                _service.SendAsync(id, BufferDataAnalysis.DataCombine(SN, 0x01, data));
            }
            catch (Exception e)
            {
                _logger.LogError("Error:" + e);
            }
        }

        /// <summary>
        /// 上位机调度系统回复收到码垛结果
        /// </summary>
        /// <param name="SN">SN码</param>
        /// <param name="id">客户端ID</param>
        public void SendReplayStackResult(byte[] SN, string id)
        {
            try
            {
                _service.SendAsync(id, BufferDataAnalysis.DataCombine(SN, 0x02, new byte[0]));
            }
            catch (Exception e)
            {
                _logger.LogError("Error:" + e);
            }
        }

        /// <summary>
        /// 码垛结束，请求视觉系统复位
        /// </summary>
        /// <param name="SN">SN码</param>
        /// <param name="id">客户端ID</param>
        public void SendStackOverRequestVisionSysReplace(byte[] SN, string id)
        {
            try
            {
                _service.SendAsync(id, BufferDataAnalysis.DataCombine(SN, 0x03, new byte[0]));
            }
            catch (Exception e)
            {
                _logger.LogError("Error:" + e);
            }
        }

        /// <summary>
        /// 上位机调度系统回复收到人工异常处理
        /// </summary>
        /// <param name="SN">SN码</param>
        /// <param name="id">客户端ID</param>
        public void SendReplyGetManualException(byte[] SN, string id)
        {
            try
            {
                _service.SendAsync(TestClientID, BufferDataAnalysis.DataCombine(SN, 0x04, new byte[0]));
            }
            catch (Exception e)
            {
                _logger.LogError("Error:" + e);
            }
        }

        /// <summary>
        /// 上位机调度系统请求视觉系统状态（默认SN）
        /// </summary>
        /// <param name="id">客户端ID</param>
        public void SendRequestVisionSysState(string id)
        {
            SendRequestVisionSysState(new byte[2] { 0x00, 0x00 }, id);
        }

        /// <summary>
        /// AMR就绪，请求视觉开始工作（默认SN）
        /// </summary>
        /// <param name="data">数据体</param>
        /// <param name="id">客户端ID</param>
        public void SendAMRRequestVisionStartWork(byte[] data, string id)
        {
            SendAMRRequestVisionStartWork(new byte[2] { 0x00, 0x00 }, data, id);
        }

        /// <summary>
        /// 上位机调度系统回复收到码垛结果（默认SN）
        /// </summary>
        /// <param name="id">客户端ID</param>
        public void SendReplayStackResult(string id)
        {
            SendReplayStackResult(new byte[2] { 0x00, 0x00 }, id);
        }

        /// <summary>
        /// 码垛结束，请求视觉系统复位（默认SN）
        /// </summary>
        /// <param name="id">客户端ID</param>
        public void SendStackOverRequestVisionSysReplace(string id)
        {
            SendStackOverRequestVisionSysReplace(new byte[2] { 0x00, 0x00 }, id);
        }

        /// <summary>
        /// 上位机调度系统回复收到人工异常处理（默认SN）
        /// </summary>
        /// <param name="id">客户端ID</param>
        public void SendReplyGetManualException(string id)
        {
            SendReplyGetManualException(new byte[2] { 0x00, 0x00 }, id);
        }

        #endregion

        /// <summary>
        /// 上位机调度系统每隔固定时间，请求视觉系统状态
        /// </summary>
        public void VisionStateRequest(int port)
        {
            SendRequestVisionSysState(port.ToString());
        }

        /// <summary>
        /// AMR就绪，请求视觉开始工作
        /// </summary>
        public void RequestVisionStartWork(StackState state, int port)
        {
            SendAMRRequestVisionStartWork(new byte[1] { (byte)state }, port.ToString());
        }

        /// <summary>
        /// 一次码垛完成，发送码垛结果
        /// </summary>
        public void StackResultSend(TcpVisionEntity entity, string id)
        {
            SendReplayStackResult(id);
        }

        /// <summary>
        /// 码垛结束，请求视觉系统复位
        /// </summary>
        public void RequestVisionReplace(int port)
        {
            SendStackOverRequestVisionSysReplace(port.ToString());
        }

        /// <summary>
        /// 人工异常处理完成并更新计数
        /// </summary>
        public void ManualExceptionDealDone(TcpVisionEntity entity, string id)
        {
            SendReplyGetManualException(id);
        }

        public void InitGetVisionMessage()
        {
            ReceiveVisionSysStateEvent = (entity, id) =>
            {
                _logger.LogInformation("视觉系统被动反馈给上位机调度系统状态，端口：" + id);
            };

            ReceiveVisionStartWorkEvent = (entity, id) =>
            {
                _logger.LogInformation("视觉系统回复给上位机调度系统开始工作状态，端口：" + id);
            };

            ReceiveStackRobotLocationEvent = (entity, id) =>
            {
                _logger.LogInformation("视觉系统回复机器人复位结果，端口：" + id);
            };
        }
    }

    public enum StackState
    {
        /// <summary>
        /// 复合机器人码垛无需定位
        /// </summary>
        AMRNoPositioning = 0x00,

        /// <summary>
        /// 复合机器人码垛需要定位
        /// </summary>
        AMRNeedPositioning = 0x01,

        /// <summary>
        /// 搬运机器人码垛无需定位
        /// </summary>
        RGVNoPositioning = 0x10,

        /// <summary>
        /// 搬运机器人码垛需要定位
        /// </summary>
        RGVNeedPositioning = 0x11,
    }

}
