using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Text;
using System.Threading;
using FundamentalLib;


namespace MedullaAdapter
{
    public class DiverCommunication
    {
        private byte[] _receiveBytes ;
        private SerialPort _port;
        private int _state = 0;
        private List<byte> _receiveList = new List<byte>();
        private int _length = 0;
        
        private MCUInterface<DiverCartDefinition> _interface;

        public DiverCommunication(string name, int baudRate)
        {
            _interface = new MCUInterface<DiverCartDefinition>();
            _port = new SerialPort();
            _port.PortName = name; // 根据你的实际串口名称修改
            _port.BaudRate = baudRate;
            _port.Parity = Parity.None;
            _port.DataBits = 8;
            _port.StopBits = StopBits.One;
            _port.Handshake = Handshake.None;
            _port.Open();
            Console.WriteLine($"buffer:{_port.ReadBufferSize}");
            //_port.DataReceived += OnDataReceived;
            new Thread(() =>
            {
                while (true)
                {
                    Thread.Sleep(10);
                    try
                    {
                        int bytesToRead = _port.BytesToRead;
                        if (bytesToRead > 0)
                        {
                            var readBuffer = new byte[bytesToRead];
                            var start = DateTime.Now;
                            _port.Read(readBuffer, 0, bytesToRead);
                            var time1 = DateTime.Now - start;
                            ProcessBuffer(readBuffer);
                            var time2 = DateTime.Now - start;
                            Hedingben.ToastText($"total time:{time2.TotalMilliseconds},read time:{time1},read count:{bytesToRead}", "timeDebug");
                        }
                    }
                    catch (Exception exception)
                    {
                        Console.WriteLine(exception);
                    }
                }
            }).Start();
        }

        private void ProcessBuffer(byte[] buffer)
        {
            for (int i = 0; i < buffer.Length; i++)
            {
                var newByte = buffer[i];
                switch (_state)
                {
                    case 0:
                        _receiveList.Clear();
                        if (newByte == 0xBB)
                        {
                            _receiveList.Add(newByte);
                            _state = 1;
                        }
                        break;
                    case 1:
                        if (newByte == 0xAA)
                        {
                            _receiveList.Add(newByte);
                            _state = 2;
                        }
                        else
                        {
                            _state = 0;
                        }
                        break;
                    case 2:
                        _receiveList.Add(newByte);
                        if (_receiveList.Count >= 4)
                        {
                            _length = BitConverter.ToUInt16(_receiveList.ToArray(), 2);
                        }

                        if (_receiveList.Count == _length + 7)
                        {
                            _state = 0;
                            if (_receiveList[_receiveList.Count - 1] == 0xEE)
                            {
                                _receiveBytes = _receiveList.ToArray();
                                Hedingben.ToastText($"receive from mcu:{BitConverter.ToString(_receiveBytes)}","DiverReceive");
                                if (_receiveBytes[5] == 0xA0)
                                {
                                    var dataLength1 = BitConverter.ToUInt32(_receiveBytes, 6);
                                    var data1 = new byte[dataLength1];
                                    Array.Copy(_receiveBytes, 14, data1, 0, dataLength1);
                                    MCUInterface<DiverCartDefinition>.NotifyLowerData("default", data1);
                                    var logBytes = new byte[BitConverter.ToInt32(_receiveBytes, 10)];
                                    var memorySize = BitConverter.ToInt32(_receiveBytes, 6);
                                    if (logBytes.Length > 0)
                                    {
                                        Array.Copy(_receiveBytes, 14 + memorySize, logBytes, 0, logBytes.Length);
                                        string log = System.Text.Encoding.ASCII.GetString(logBytes);
                                        string[] result = log.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None);
                                        for (int j = 0; j < result.Length; j++)
                                        {
                                            Hedingben.ToastText(result[j], $"mcuLog" + j);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                _state = 0;
                                Hedingben.ToastText($"mcu date error,should end with 0xEE , actual {_receiveList[_receiveList.Count - 1]}","DiverError");
                            }
                        }
                        break;
                    default:break;
                }
            }
        }

        public void SendMessage(byte[] data)
        {
            Hedingben.ToastText($"send to mcu:{BitConverter.ToString(data)}", "DiverSend");
            _port.Write(data, 0, data.Length);
        }

        public byte[] GetMessage()
        {
            return _receiveBytes;
        }
    }
}
