using DotNetty.Buffers;
using DotNetty.Transport.Channels;
using Microsoft.Extensions.Logging;
using NearCardAttendance.Service.TcpServer.Protocol;
using System;
using System.Text;

namespace NearCardAttendance.Service.TcpServer.Handler
{
    public class ProtocolHandler : SimpleChannelInboundHandler<IByteBuffer>
    {
        private IByteBuffer? buffer;
        private readonly ILogger<ProtocolHandler> _logger;

        public ProtocolHandler(ILogger<ProtocolHandler> logger)
        {
            _logger = logger;
        }

        public override async void ChannelActive(IChannelHandlerContext context)
        {
            // Handle channel active event
        }

        public override void ChannelInactive(IChannelHandlerContext context)
        {
            ReleaseBuffer();
            base.ChannelInactive(context);
        }

        protected override void ChannelRead0(IChannelHandlerContext context, IByteBuffer message)
        {
            try
            {
                string content = message.ToString(Encoding.ASCII);
                _logger.LogInformation($"{nameof(ProtocolHandler)} -- {nameof(ChannelRead0)} -- 最开始接受内容:{content}");

                ProcessMessage(context, content);
            }
            catch (Exception ex)
            {
                ReleaseBuffer();
                _logger.LogInformation($"{nameof(ProtocolHandler)} --- {nameof(ChannelRead0)} 处理出错\n{ex.Message}\n{ex.StackTrace}");
            }
        }
        private void ProcessMessage(IChannelHandlerContext context, string content)
        {
            buffer ??= Unpooled.Buffer();

            byte[] bytes = Encoding.ASCII.GetBytes(content);
            buffer.WriteBytes(Unpooled.WrappedBuffer(bytes));

            if (int.TryParse(buffer.ToString(Encoding.ASCII).Substring(0, 4), out int messageLength))
            {
                Console.WriteLine(buffer.ToString(Encoding.ASCII));
                if (buffer.ToString(Encoding.ASCII).Length == messageLength)
                {
                    //var parser = buffer.ToString(Encoding.ASCII);
                    ProtocolParser parser = new(buffer.ToString(Encoding.ASCII));
                    context.FireChannelRead(parser);
                    //Console.WriteLine($"发送正常:{parser}");
                    //ProtocolWrapper wrapper = new ProtocolWrapper("82", parser.SeqNo, DateTime.Now.ToString("yyyyMMddHHmmss"));
                    //Console.WriteLine(wrapper.GenerateProtocolString());
                    //Console.WriteLine($"length:{parser.MessageLength},func_no:{parser.FuncNo},seq_no:{parser.SeqNo},data:{parser.Data}");
                    ReleaseBuffer();
                }
                else if (buffer.ToString(Encoding.ASCII).Length > messageLength)
                {
                    string inputString = buffer.ToString(Encoding.ASCII);
                    var nextMessageLength = messageLength;
                    var startIndex = 0;
                    var messagesStringLength = 0;

                    List<string> messages = new List<string>();

                    while (startIndex < inputString.Length)
                    {
                        try
                        {
                            string message = inputString.Substring(startIndex, nextMessageLength);
                            messages.Add(message);

                            startIndex += nextMessageLength;

                            if (startIndex + 4 <= inputString.Length)
                            {
                                if (!int.TryParse(inputString.Substring(startIndex, 4), out nextMessageLength))
                                {
                                    break;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                        catch (Exception)
                        {
                            break;
                        }
                        
                    }

                    foreach (var message in messages)
                    {
                        ProtocolParser parser = new(message);
                        context.FireChannelRead(parser);
                        messagesStringLength += message.Length;
                       // Console.WriteLine(message);
                    }
                    // 过长且不完整
                    if (inputString.Length > messageLength)
                    {
                        var overLongbuffer = Unpooled.Buffer();
                        overLongbuffer.WriteBytes(Unpooled.WrappedBuffer(Encoding.ASCII.GetBytes(inputString.Substring(messageLength, inputString.Length- messageLength))));
                        ReleaseBuffer();
                        buffer = overLongbuffer;
                    }
                    // 数据完整
                    if (inputString.Length ==messageLength)
                    {
                        ReleaseBuffer();
                    }
                    //Console.WriteLine($"{stringLength},{inputString.Length}");


                    // var parser = buffer.ToString(Encoding.ASCII).Substring(0, messageLength);
                    //ProtocolParser parser = new(buffer.ToString(Encoding.ASCII).Substring(0, messageLength));
                    //context.FireChannelRead(parser);
                    ////ReleaseBuffer();

                    //var overLongbuffer = Unpooled.Buffer();
                    //Console.WriteLine($"过长消息:{buffer.ToString(Encoding.ASCII).Substring(messageLength)}");
                    //overLongbuffer.WriteBytes(Unpooled.WrappedBuffer(Encoding.ASCII.GetBytes(buffer.ToString(Encoding.ASCII).Substring(messageLength))));
                    //ReleaseBuffer();
                    //buffer = overLongbuffer;
                    //Console.WriteLine($"剩余消息{buffer.ToString(Encoding.ASCII)}");
                }
            }
        }

        private void ProcessMessage2(IChannelHandlerContext context, string content)
        {
            buffer ??= Unpooled.Buffer();

            byte[] bytes = Encoding.ASCII.GetBytes(content);
            buffer.WriteBytes(Unpooled.WrappedBuffer(bytes));

            if (int.TryParse(buffer.ToString(Encoding.ASCII).Substring(0, 4), out int messageLength))
            {
                Console.WriteLine(buffer.ToString(Encoding.ASCII));
                if (buffer.ToString(Encoding.ASCII).Length == messageLength)
                {
                    //var parser = buffer.ToString(Encoding.ASCII);
                    ProtocolParser parser = new(buffer.ToString(Encoding.ASCII));
                    context.FireChannelRead(parser);
                    Console.WriteLine($"发送正常:{parser}");
                    //ProtocolWrapper wrapper = new ProtocolWrapper("82", parser.SeqNo, DateTime.Now.ToString("yyyyMMddHHmmss"));
                    //Console.WriteLine(wrapper.GenerateProtocolString());
                    Console.WriteLine($"length:{parser.MessageLength},func_no:{parser.FuncNo},seq_no:{parser.SeqNo},data:{ parser.Data}");
                    ReleaseBuffer();
                }
                else if (buffer.ToString(Encoding.ASCII).Length > messageLength)
                {
                    // var parser = buffer.ToString(Encoding.ASCII).Substring(0, messageLength);
                    ProtocolParser parser = new(buffer.ToString(Encoding.ASCII).Substring(0, messageLength));
                    context.FireChannelRead(parser);
                    //ReleaseBuffer();

                    var overLongbuffer = Unpooled.Buffer();
                    Console.WriteLine($"过长消息:{buffer.ToString(Encoding.ASCII).Substring(messageLength)}");
                    overLongbuffer.WriteBytes(Unpooled.WrappedBuffer(Encoding.ASCII.GetBytes(buffer.ToString(Encoding.ASCII).Substring(messageLength))));
                    ReleaseBuffer();
                    buffer = overLongbuffer;
                    Console.WriteLine($"剩余消息{buffer.ToString(Encoding.ASCII)}");
                }
            }
        }

        private void ReleaseBuffer()
        {
            buffer?.Release();
            buffer = null;
        }
    }
}