using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Net.Sockets;
using System.Threading;

namespace SLZ_4
{
    public class ScanNetwork : IDisposable   // TCP扫码枪客户端类
    {
        private TcpClient tcpClient;
        private NetworkStream networkStream;
        private string ipAddress;
        private int port;
        public int codeLength;
        private readonly Action<string> onDataReceived;
        private readonly Action<string> onErrorReceived;
        private readonly Action<string> onStatusUpdate;
        public bool isRunning { get; set; }

        public bool IsConnected
        {
            get
            {
                return tcpClient?.Client != null &&
                       tcpClient.Connected &&
                       networkStream?.CanRead == true;
            }
        }

        public ScanNetwork(string ip, int iport, int icodeLength,
                          Action<string> ionDataReceived,
                          Action<string> ionError,
                          Action<string> ionStatusUpdate)
        {
            ipAddress = ip;
            port = iport;
            codeLength = icodeLength;
            onDataReceived = ionDataReceived;
            onErrorReceived = ionError;
            onStatusUpdate = ionStatusUpdate;
        }

        public bool Connect()
        {
            string str = "";
            try
            {
                tcpClient = new TcpClient();
                tcpClient.Connect(ipAddress, port);
                networkStream = tcpClient.GetStream();
                isRunning = true;

                // 启动接收线程
                Thread receiveThread = new Thread(ReceiveData);
                receiveThread.IsBackground = true;
                receiveThread.Start();

                str = "TCP扫码枪连接成功:" + ipAddress + ":" + port;
                onStatusUpdate?.Invoke(str);
                FileLogger.Log(str, LogLevel.INFO);
                return true;
            }
            catch (Exception ex)
            {
                str = $"连接TCP扫码枪失败: {ex.Message} {ipAddress} : {port}";
                onStatusUpdate?.Invoke(str);
                FileLogger.Log(str, LogLevel.ERROR);
                return false;
            }
        }

        public bool Reconnect(string newIp, int newPort)
        {
            // 先断开当前连接
            Disconnect();

            // 更新IP和端口
            ipAddress = newIp;
            port = newPort;

            // 重新连接
            return Connect();
        }

        public void Disconnect()
        {
            isRunning = false;
            networkStream?.Close();
            tcpClient?.Close();
            string str = "TCP扫码枪已断开: " + ipAddress + ":" + port;
            onStatusUpdate?.Invoke(str);
            FileLogger.Log(str, LogLevel.WARNING);
        }

        public void SendStartCommand()
        {
            try
            {
                if (IsConnected)
                {
                    string data = "73 74 61 72 74";
                    byte[] byt = StrtoHexbyte(data);
                    networkStream.Write(byt, 0, byt.Length);
                }
                else
                {
                    onErrorReceived?.Invoke("发送扫码启动失败: 连接已断开");
                }
            }
            catch (Exception ex)
            {
                onErrorReceived?.Invoke($"发送扫码启动失败: {ex.Message}");
                Connect_Error();
            }
        }

        private void ReceiveData()
        {
            byte[] buffer = new byte[1024];

            while (isRunning)
            {
                try
                {
                    // 检查真实连接状态
                    if (!IsConnected)
                    {
                        onStatusUpdate?.Invoke("扫码枪连接已断开，尝试重连...");
                        Reconnect(ipAddress, port); // 自动重连
                        Thread.Sleep(2000);
                        continue;
                    }

                    if (networkStream?.DataAvailable == true)
                    {
                        int bytesRead = networkStream.Read(buffer, 0, buffer.Length);
                        if (bytesRead > 0)
                        {
                            string code = Encoding.Default.GetString(buffer, 0, bytesRead);
                            string cleanCode = code.Replace("\r\n", "").Trim();
                            onDataReceived?.Invoke(cleanCode);

                            if (cleanCode.Length != codeLength)
                            {
                                onStatusUpdate?.Invoke($"当前条形码长度为{cleanCode.Length}，所设置的条码长度为{codeLength}");
                            }
                        }
                    }
                    Thread.Sleep(100); // 稍微延迟以减少CPU占用
                }
                catch (Exception ex)
                {
                    onErrorReceived?.Invoke($"扫码枪接收数据异常: {ex.Message}");
                    Connect_Error();
                    Thread.Sleep(1000);
                }
            }
        }

        // l连接异常
        private void Connect_Error()
        {
            isRunning = false;
            networkStream?.Close();
            tcpClient?.Close();

            string str = $"扫码枪连接异常，已断开: {ipAddress}:{port}";
            onStatusUpdate?.Invoke(str);
            FileLogger.Log(str, LogLevel.WARNING);
        }

        //将发送数据转为十六进制数据
        public static byte[] StrtoHexbyte(string hexString)
        {
            hexString = hexString.Replace(" ", "");
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
            {
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            }
            return returnBytes;
        }

        public void Dispose()
        {
            Disconnect();
            tcpClient?.Dispose();
            networkStream?.Dispose();
        }        
    }
}