using System;
using System.Drawing;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Linq;
using System.Diagnostics;
using Sunny.UI;

namespace SLC1_N
{
    public partial class Form_NetworkSet : Form
    {
        public Form_NetworkSet()
        {
            InitializeComponent();
        }

        private void ConfigTCP_Load(object sender, EventArgs e)
        {
            

            ch1ipaddress = Form1.f1.LL28CH1client.IP;
            ch2ipaddress = Form1.f1.LL28CH2client.IP;

            ReadConn.Interval = 500; // 连接状态定时器
            ReadConn.Start();
        }

        // 连接状态定时器
        private void ReadConn_Tick(object sender, EventArgs e)
        {
            // CH1
            if (Form1.f1.LL28CH1client != null && Form1.f1.LL28CH1client.isRunning)
            {
                lb_CH1Communication_status.Text = "OK";
                lb_CH1Communication_status.ForeColor = Color.Green;
            }
            else
            {
                lb_CH1Communication_status.Text = "NG";
                lb_CH1Communication_status.ForeColor = Color.Red;
            }
            lb_CH1IP.Text = ch1ipaddress;

            // CH2
            if (Form1.f1.LL28CH2client != null && Form1.f1.LL28CH2client.isRunning)
            {
                lb_CH2Communication_status.Text = "OK";
                lb_CH2Communication_status.ForeColor = Color.Green;
            }
            else
            {
                lb_CH2Communication_status.Text = "NG";
                lb_CH2Communication_status.ForeColor = Color.Red;
            }
            lb_CH2IP.Text = ch2ipaddress;

            // CH3
            if (Form1.f1.LL28CH3client != null && Form1.f1.LL28CH3client.isRunning)
            {
                lb_CH3Communication_status.Text = "OK";
                lb_CH3Communication_status.ForeColor = Color.Green;
            }
            else
            {
                lb_CH3Communication_status.Text = "NG";
                lb_CH3Communication_status.ForeColor = Color.Red;
            }
            lb_CH3IP.Text = ch3ipaddress;

            // CH4
            if (Form1.f1.LL28CH4client != null && Form1.f1.LL28CH4client.isRunning)
            {
                lb_CH4Communication_status.Text = "OK";
                lb_CH4Communication_status.ForeColor = Color.Green;
            }
            else
            {
                lb_CH4Communication_status.Text = "NG";
                lb_CH4Communication_status.ForeColor = Color.Red;
            }
            lb_CH4IP.Text = ch4ipaddress;

            lb_ComputerIP.Text = Form1.f1.localipaddress;
        }

        // CH1重连按钮
        private void CH1TCPReCon_Click(object sender, EventArgs e)
        {
            bt_CH1TCPReconnect.Enabled = false;
            Form1.f1.LL28CH1client?.Stop(); // 先停止线程（如果正在运行）
            Form1.f1.LL28CH1client?.Disconnect(); // 断开旧连接
            Form1.f1.LL28CH1client?.Connect(lb_CH1IP.Text); // 连接新 IP
            Form1.f1.LL28CH1client?.Start(); // 重新启动线程

            // 本地保存
            var jsconfig = new JsonConfig("config.json");
            jsconfig.SetValue("ch1ipaddress", lb_CH1IP.Text);
            bt_CH1TCPReconnect.Enabled = true;

            // 同步
            Form1.f1.ch1ipaddress = lb_CH1IP.Text;
        }

        // CH1断开连接
        private void CH1TCPBreak_Click(object sender, EventArgs e)
        {
            Form1.f1.LL28CH1client?.Disconnect(); // 断开旧连接
        }

        // CH2重连按钮
        private void CH2TCPReCon_Click(object sender, EventArgs e)
        {
            Form1.f1.LL28CH2client?.Stop(); // 先停止线程（如果正在运行）
            Form1.f1.LL28CH2client?.Disconnect(); // 断开旧连接
            Form1.f1.LL28CH2client?.Connect(lb_CH2IP.Text); // 连接新 IP
            Form1.f1.LL28CH2client?.Start(); // 重新启动线程

            // 本地保存
            var jsconfig = new JsonConfig("config.json");
            jsconfig.SetValue("ch2ipaddress", lb_CH2IP.Text);

            // 同步
            Form1.f1.ch2ipaddress = lb_CH2IP.Text; 
        }

        // CH2断开连接
        private void CH2TCPBreak_Click(object sender, EventArgs e)
        {
            Form1.f1.LL28CH2client?.Disconnect(); // 断开旧连接
        }

        // CH3重连按钮
        private void bt_CH3TCPReconnect_Click(object sender, EventArgs e)
        {
            Form1.f1.LL28CH3client?.Stop(); // 先停止线程（如果正在运行）
            Form1.f1.LL28CH3client?.Disconnect(); // 断开旧连接
            Form1.f1.LL28CH3client?.Connect(lb_CH3IP.Text); // 连接新 IP
            Form1.f1.LL28CH3client?.Start(); // 重新启动线程

            // 本地保存
            var jsconfig = new JsonConfig("config.json");
            jsconfig.SetValue("ch3ipaddress", lb_CH3IP.Text);

            // 同步
            Form1.f1.ch3ipaddress = lb_CH3IP.Text;
        }

        // CH3断开连接
        private void CH3TCPBreak_Click(object sender, EventArgs e)
        {
            Form1.f1.LL28CH3client?.Disconnect(); // 断开旧连接
        }

        // CH4重连按钮
        private void bt_CH4TCPReconnect_Click(object sender, EventArgs e)
        {
            Form1.f1.LL28CH4client?.Stop(); // 先停止线程（如果正在运行）
            Form1.f1.LL28CH4client?.Disconnect(); // 断开旧连接
            Form1.f1.LL28CH4client?.Connect(lb_CH4IP.Text); // 连接新 IP
            Form1.f1.LL28CH4client?.Start(); // 重新启动线程

            // 本地保存
            var jsconfig = new JsonConfig("config.json");
            jsconfig.SetValue("ch4ipaddress", lb_CH4IP.Text);

            // 同步
            Form1.f1.ch4ipaddress = lb_CH4IP.Text;
        }

        // CH4断开连接
        private void CH4TCPBreak_Click(object sender, EventArgs e)
        {
            Form1.f1.LL28CH4client?.Disconnect(); // 断开旧连接
        }

        // 搜索IP按钮
        private void UDPReadIP_Click(object sender, EventArgs e)
        {
            bt_UDPReadIP.Enabled = false;
            try
            {
                UDPBroadcast();
            }
            finally
            {
                bt_UDPReadIP.Enabled = true;
            }
        }

        string ch1ipaddress = null;  // 通道1的IP地址
        string ch2ipaddress = null;  // 通道2的IP地址
        string ch3ipaddress = null;  // 通道1的IP地址
        string ch4ipaddress = null;  // 通道2的IP地址
        string UDP_recvdata = "";    // 存储接收到的UDP数据
        Socket udpsock;                 // UDP套接字
        Thread UDPlisten;

        private bool isUDPRunning = false;  // UDP运行标志位

        // 执行UDP广播搜索IP地址
        private void UDPBroadcast()
        {
            try
            {
                if (isUDPRunning && udpsock != null)
                {
                    Console.WriteLine("UDP广播已在运行中，直接发送广播消息...");

                    // 发送广播消息
                    byte[] sdata = Encoding.ASCII.GetBytes("hello,udp server");

                    string localIP = GetLocalIP();
                    if (localIP.Length > 1)
                    {
                        int lastIndex = localIP.LastIndexOf(".");
                        string broadcastip = localIP.Remove(lastIndex + 1) + "255";
                        IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse(broadcastip), 9999);

                        udpsock.SendTo(sdata, ipEndPoint);
                    }
                    return;
                }

                isUDPRunning = true;  
                ch1ipaddress = null;
                ch2ipaddress = null;
                ch3ipaddress = null;
                ch4ipaddress = null;

                UDP_recvdata = "";

                if (udpsock != null) // 关闭旧的
                {
                    udpsock.Close();
                    udpsock = null;
                }

                string PrefixIP = GetLocalIP(); // 获取本机IP
                if (PrefixIP.Length <= 1) return;

                // 设置广播地址
                int lastDotIndex = PrefixIP.LastIndexOf(".");
                string broadcastIP = PrefixIP.Remove(lastDotIndex + 1) + "255";

                // 初始化UDP套接字
                udpsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

                udpsock.Bind(new IPEndPoint(IPAddress.Any, 0));  // 0 表示由系统分配空闲端口

                IPEndPoint broadcastEndPoint = new IPEndPoint(IPAddress.Parse(broadcastIP), 9999);
                udpsock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); // 启用套接字的广播功能

                UDPlisten = new Thread(Thread_UDPListen); // 启动监听线程
                UDPlisten.IsBackground = true;
                UDPlisten.Start();

                // 发送广播消息
                byte[] data = Encoding.ASCII.GetBytes("hello,udp server");
                udpsock.SendTo(data, broadcastEndPoint);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"UDPBroadcast()异常: {ex.Message}");
                mxlLog.Instance.Error($"UDPBroadcast()异常,行号{ex.StackTrace} ", ex);
            }
        }

        // 获取本机IP地址前缀(192.168.1.x)
        public string GetLocalIP()
        {
            IPAddress[] ipArray = Dns.GetHostAddresses(Dns.GetHostName());

            foreach (var ip in ipArray)
            {
                if (IsIPInRange(ip.ToString(), "192.168.1.0", "192.168.1.255"))
                {
                    return ip.ToString();
                }
            }

            // 如果没有找到192.168.1.x的IP，返回第一个IPv4地址
            return ipArray.First(ip => ip.AddressFamily == AddressFamily.InterNetwork).ToString();
        }

        // 检查IP地址是否在指定范围内
        public bool IsIPInRange(string input, string rangeStart, string rangeEnd)
        {
            uint ipValue = IPToUInt(input);
            return ipValue >= IPToUInt(rangeStart) && ipValue <= IPToUInt(rangeEnd);
        }

        // 将IP地址转换为无符号整数用于比较
        private uint IPToUInt(string ipAddress)
        {
            if (!IPAddress.TryParse(ipAddress, out var ip))
            {
                return 0;
            }

            byte[] bytes = ip.GetAddressBytes();
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(bytes);
            }

            return BitConverter.ToUInt32(bytes, 0);
        }

        // UDP监听线程：持续接收响应数据
        private  void Thread_UDPListen()
        {
            try
            {
                // 设置接收超时
                udpsock.ReceiveTimeout = 1000; // 1秒超时

                while (isUDPRunning && udpsock != null && udpsock.IsBound)  
                {
                    try
                    {
                        byte[] data = new byte[1024];
                        int rbytes = udpsock.Receive(data); // 244
                        string rdata = Encoding.ASCII.GetString(data, 0, rbytes);
                        Console.WriteLine($"UDP监听线程rdata: {rdata}");

                        UDP_recvdata += rdata + "\n";
                        ParseUDPdata(); // 解析接收到的数据
                    }
                    catch (SocketException ex) when (ex.SocketErrorCode == SocketError.TimedOut)
                    {
                        continue; // 超时是正常滴，继续循环
                    }
                    catch (SocketException ex) when (ex.SocketErrorCode == SocketError.Interrupted)
                    {
                        Console.WriteLine("UDP接收被正常中断");
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                mxlLog.Instance.Error($"UDP监听线程异常,行号{ex.StackTrace} ", ex);
            }
            finally
            {
                isUDPRunning = false;  
            }
        }

        /* 解析UDP响应数据，提取通道、IP地址
         * 数据格式示例:
         * 1:192.168.1.10 \n
         * 2:192.168.1.11
         */
        public void ParseUDPdata()
        {
            try
            {
                if (string.IsNullOrEmpty(UDP_recvdata)) return;

                Console.WriteLine($"UDP_recvdata: {UDP_recvdata}");
                ch1ipaddress = null;
                ch2ipaddress = null;
                ch3ipaddress = null;
                ch4ipaddress = null;

                string[] iparr = UDP_recvdata.Split('\n');

                foreach (string ipdata in iparr)
                {
                    if (string.IsNullOrEmpty(ipdata)) continue;

                    string[] chorip = ipdata.Split(':');
                    if (chorip.Length != 2) continue;

                    int ch = Convert.ToInt32(chorip[0]);
                    string ip = chorip[1];

                    switch (ch)
                    {
                        case 1: ch1ipaddress = ip; break;
                        case 2: ch2ipaddress = ip; break;
                        case 3: ch3ipaddress = ip; break;
                        case 4: ch4ipaddress = ip; break;
                    }
                }
            }
            catch (Exception ex)
            {
                // 错误处理代码...
                mxlLog.Instance.Error($"ParseUDPdata()异常,行号{ex.StackTrace} ", ex);
            }
        }

        // 窗口关闭
        private void ConfigTCP_FormClosing(object sender, FormClosingEventArgs e)
        {
            StopUDP();
            //UDPlisten?.Join(500);
        }

        // 停止UDP
        public void StopUDP()
        {
            isUDPRunning = false;
            if (udpsock != null)
            {
                udpsock.Close();
                udpsock = null;
            }
        }


        /**/
    }
}
