using MetroFramework.Forms;
using MQTTnet;
using MQTTnet.Core;
using MQTTnet.Core.Client;
using MQTTnet.Core.Packets;
using MQTTnet.Core.Protocol;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MqttClientWin
{
    public partial class FmMqttClient : MetroForm
    {
        private MqttClient mqttClient = null;

        public FmMqttClient()
        {
            InitializeComponent();
            txtSubTopic.Text = "/Uplink";
            txtSubService.Text = "mqtt.usot.top";
            txtReceiveMessage.AppendText("Copyright © 2025 路怀帅. All rights reserved." + Environment.NewLine);
        }

        // <summary>
        // 服务器连接成功
        // </summary>
        // <param name="sender"></param>
        // <param name="e"></param>
        private void MqttClient_Connected(object sender, EventArgs e)
        {
            Invoke((new Action(() =>
            {
                txtReceiveMessage.AppendText("已连接到MQTT服务器！" + Environment.NewLine);
  
            })));
        }

        // <summary>
        // 断开服务器连接
        // </summary>
        // <param name="sender"></param>
        // <param name="e"></param>
        private void MqttClient_Disconnected(object sender, EventArgs e)
        {
            Invoke((new Action(() =>
            {
                txtReceiveMessage.AppendText("已断开MQTT连接！" + Environment.NewLine);
            })));
        }

        // <summary>
        // 接收到消息
        // </summary>
        // <param name="sender"></param>
        // <param name="e"></param>
        private void MqttClient_ApplicationMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e)
        {
            Invoke((Action)(() =>
            {
                // 原始消息输出到 txtReceiveMessage（保持不变）
                string payloadStr = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
                txtReceiveMessage.AppendText($">> {payloadStr}{Environment.NewLine}");
                txtMessage.Clear();
                // 结构化解析结果输出到 txtMessage
                txtMessage.AppendText($"📩 来自主题 {e.ApplicationMessage.Topic} 的消息 [{DateTime.Now:HH:mm:ss}]{Environment.NewLine}");

                try
                {
                    using (var doc = JsonDocument.Parse(payloadStr))
                    {
                        var root = doc.RootElement;

                        // 提取和显示其他信息...
                        string deviceName = root.TryGetProperty("deviceName", out var deviceNameProp) ? deviceNameProp.GetString() : "N/A";
                        string devEUI = root.TryGetProperty("devEUI", out var devEUIProp) ? devEUIProp.GetString() : "N/A";

                        string gatewayTimeStr = root.TryGetProperty("gatewayTime", out var gatewayTimeProp) ? gatewayTimeProp.GetString() : "N/A";
                        string localTime = "N/A";
                        if (!string.IsNullOrEmpty(gatewayTimeStr) && gatewayTimeStr != "N/A")
                        {
                            if (DateTimeOffset.TryParse(gatewayTimeStr, out var dto))
                            {
                                localTime = dto.LocalDateTime.ToString("yyyy-MM-dd HH:mm:ss");
                            }
                        }

                        // 提取 rxInfo[0] 中的 rssi 和 loRaSNR
                        string rssi = "N/A";
                        string loRaSNR = "N/A";

                        if (root.TryGetProperty("rxInfo", out var rxInfoArray) && rxInfoArray.ValueKind == JsonValueKind.Array && rxInfoArray.GetArrayLength() > 0)
                        {
                            var gatewayInfo = rxInfoArray[0];
                            rssi = gatewayInfo.TryGetProperty("rssi", out var rssiProp) ? rssiProp.GetInt32().ToString() : "N/A";
                            loRaSNR = gatewayInfo.TryGetProperty("loRaSNR", out var snrProp) ? snrProp.GetDouble().ToString("F1") : "N/A";
                        }

                        // 显示提取的字段
                        txtMessage.AppendText($"🔧 设备名称: {deviceName}{Environment.NewLine}");
                        txtMessage.AppendText($"📡 设备EUI: {devEUI}{Environment.NewLine}");
                        txtMessage.AppendText($"🕒 网关时间: {localTime}{Environment.NewLine}");
                        txtMessage.AppendText($"📶 信号强度 (RSSI): {rssi} dBm{Environment.NewLine}");
                        txtMessage.AppendText($"⚡ 信噪比 (LoRaSNR): {loRaSNR} dB{Environment.NewLine}");
                        // 处理解码的 data 字段
                        if (root.TryGetProperty("data", out var dataElement))
                        {
                            string base64Data = dataElement.GetString();
                            if (!string.IsNullOrEmpty(base64Data))
                            {
                                try
                                {
                                    byte[] decodedBytes = Convert.FromBase64String(base64Data);
                                    string decodedJson = Encoding.UTF8.GetString(decodedBytes);

                                    using (var innerDoc = JsonDocument.Parse(decodedJson))
                                    {
                                        var innerRoot = innerDoc.RootElement;

                                        // 更新按钮状态
                                        UpdateButtonState(innerRoot, "T", btn_t);
                                        UpdateButtonState(innerRoot, "R", btn_r);
                                        UpdateButtonState(innerRoot, "C", btn_c);

                                        // 对于E字段，由于其对应多个按钮且条件不同，单独处理
                                        if (innerRoot.TryGetProperty("E", out var eProp))
                                        {
                                            string eStr = eProp.GetString();
                                            if (int.TryParse(eStr, out int eValue))
                                            {
                                                btn_s.BackColor = (eValue == 3) ? Color.Lime : Color.Gainsboro;
                                                btn_q.BackColor = (eValue == 4) ? Color.Lime : Color.Gainsboro;
                                                btn_e.BackColor = (eValue == 5) ? Color.Lime : Color.Gainsboro;
                                                btn_m.BackColor = (eValue == 6) ? Color.Lime : Color.Gainsboro;
                                                btn_p.BackColor = (eValue == 7) ? Color.Lime : Color.Gainsboro;
                                                btn_n.BackColor = (eValue == 8) ? Color.Lime : Color.Gainsboro;
                                            }
                                            else
                                            {
                                                btn_s.BackColor = Color.Gainsboro;
                                                btn_q.BackColor = Color.Gainsboro;
                                                btn_e.BackColor = Color.Gainsboro;
                                                btn_m.BackColor = Color.Gainsboro;
                                                btn_p.BackColor = Color.Gainsboro;
                                                btn_n.BackColor = Color.Gainsboro;

                                            }
                                        }

                                        string prettyJson = innerRoot.ToString(); // 自动格式化
                                        txtMessage.AppendText($"📦 Data解码:{prettyJson}{Environment.NewLine}");
                                    }
                                }
                                catch (FormatException)
                                {
                                    txtMessage.AppendText($"❌ Base64 解码失败: 数据格式错误{Environment.NewLine}");
                                }
                                catch (Exception ex)
                                {
                                    txtMessage.AppendText($"❌ 解码异常: {ex.Message}{Environment.NewLine}");
                                }
                            }
                            else
                            {
                                txtMessage.AppendText($"📦 Base64 data: (空){Environment.NewLine}");
                            }
                        }
                        else
                        {
                            txtMessage.AppendText($"📦 Base64 data: (未找到字段){Environment.NewLine}");
                        }
                    }
                }
                catch (Exception ex)
                {
                    txtMessage.AppendText($"❌ JSON 解析失败: {ex.Message}{Environment.NewLine}{Environment.NewLine}");
                }
            }));
        }

        // 通用按钮状态更新方法
        private void UpdateButtonState(JsonElement root, string fieldName, Button button)
        {
            if (root.TryGetProperty(fieldName, out var fieldProp))
            {
                string valueStr = fieldProp.GetString(); // 先作为字符串获取

                if (int.TryParse(valueStr, out int value))
                {
                    bool isOn = (value == 1);
                    button.BackColor = isOn ? Color.Lime : Color.Gainsboro;
      
                }

            }

        }

        // <summary>
        // 订阅消息
        // </summary>
        // <param name="sender"></param>
        // <param name="e"></param>
        private async void BtnSubscribe_ClickAsync(object sender, EventArgs e)
        {
            string broker = txtSubService.Text.Trim();
            string topic = txtSubTopic.Text.Trim();

            if (string.IsNullOrEmpty(broker))
            {
                MessageBox.Show("MQTT 服务器地址不能为空！");
                return;
            }

            if (string.IsNullOrEmpty(topic))
            {
                MessageBox.Show("订阅主题不能为空！");
                return;
            }

            // 断开旧连接（如果已连接）
            if (mqttClient != null && mqttClient.IsConnected)
            {
                await mqttClient.DisconnectAsync();
            }

            // 初始化客户端（如果尚未创建）
            if (mqttClient == null)
            {
                mqttClient = new MqttClientFactory().CreateMqttClient() as MqttClient;
                mqttClient.ApplicationMessageReceived += MqttClient_ApplicationMessageReceived;
                mqttClient.Connected += MqttClient_Connected;
                mqttClient.Disconnected += MqttClient_Disconnected;
            }

            try
            {
                var options = new MqttClientTcpOptions
                {
                    Server = broker,
                    ClientId = Guid.NewGuid().ToString().Substring(0, 5),
                    UserName = "",
                    Password = "", // 注意：某些版本需要 char[]
                    CleanSession = true,
                    // 可选：设置端口（默认1883）
                    // Port = 1883
                };

                // 连接服务器
                await mqttClient.ConnectAsync(options);

                // 连接成功后订阅主题
                var topicFilter = new TopicFilter(topic, MqttQualityOfServiceLevel.AtMostOnce);
                await mqttClient.SubscribeAsync(topicFilter);

                Invoke(new Action(() =>
                {
                    txtReceiveMessage.AppendText($"[订阅] 已连接到 {broker} 并订阅主题: [{topic}]{Environment.NewLine}");
                    btnSubscribe.Enabled = false; // 防止重复点击
                }));
            }
            catch (Exception ex)
            {
                Invoke(new Action(() =>
                {
                    txtReceiveMessage.AppendText($"[错误] 连接或订阅失败: {ex.Message}{Environment.NewLine}");
                    MessageBox.Show($"连接失败: {ex.Message}");
                }));
            }
        }

  

        private void FmMqttClient_Load(object sender, EventArgs e)
        {

        }

        private void txtPubTopic_TextChanged(object sender, EventArgs e)
        {

        }

        private void txtSubService_TextChanged(object sender, EventArgs e)
        {

        }

        private void label4_Click(object sender, EventArgs e)
        {

        }

        private void label5_Click(object sender, EventArgs e)
        {

        }

        private void txtReceiveMessage_TextChanged(object sender, EventArgs e)
        {

        }

        private void tableLayoutPanel1_Paint(object sender, PaintEventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {

        }

        private void button2_Click(object sender, EventArgs e)
        {

        }

        private void button2_Click_1(object sender, EventArgs e)
        {

        }
    }
}