using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using FairyView;
using StandardScene.Utils;

namespace StandardScene.Charge
{
    /// <summary>
    /// 通讯监控面板（CycleGUI 版，替代原 WinForms 窗体）。
    /// <list type="bullet">
    /// <item>单实例：再次打开则把已有面板置前。</item>
    /// <item>订阅 <see cref="CommunicationMessageService.MessageAdded"/>，批量刷新 UI（500ms 节流），最多显示 100 行。</item>
    /// <item>支持 IP 筛选、暂停/继续、清空（二次确认）、选中报文解析详情。</item>
    /// </list>
    /// 保留可实例化 + <see cref="Show"/> 以兼容既有调用。
    /// </summary>
    public class CommunicationMonitorForm
    {
        private const int MaxDisplayRows = 100;
        private const int UiBatchSize = 20;
        private const int StatsRefreshMs = 500;
        private const string TableId = "comm-monitor-msgs";

        private readonly Color SendRowColor = Color.FromArgb(232, 245, 233);
        private readonly Color ReceiveRowColor = Color.FromArgb(227, 242, 253);
        private readonly Color SelectedRowColor = Color.FromArgb(255, 249, 196);

        private readonly CommunicationMessageService MessageService = CommunicationMessageService.Instance;

        private Panel _panel;
        private bool _subscribed;
        private bool _paused;
        private int _selectedIpIndex;
        private string[] _ipOptions = { "全部" };
        private int _selectedRowIndex = -1;
        private string _parsedText = "";
        private string _statsText = "";

        private List<CommunicationMessage> _displayMessages = new List<CommunicationMessage>();
        private readonly Queue<CommunicationMessage> PendingMessages = new Queue<CommunicationMessage>();
        private readonly object PendingLock = new object();

        private DateTime _lastStatsRefresh = DateTime.MinValue;
        private bool _pendingStatsRefresh;

        /// <summary>打开（或置前）通讯监控面板。兼容原 <c>new CommunicationMonitorForm().Show()</c> 调用方式。</summary>
        public void Show() => Open();

        /// <summary>打开（或置前）通讯监控面板。</summary>
        public static void Open() => (_instance ??= new CommunicationMonitorForm()).OpenCore();

        private static CommunicationMonitorForm _instance;

        private void OpenCore()
        {
            if (_panel != null)
            {
                try
                {
                    _panel.BringToFront();
                    return;
                }
                catch
                {
                    _panel = null;
                }
            }

            _paused = false;
            _selectedRowIndex = -1;
            _parsedText = "";
            RefreshIpFilter();
            ReloadFromService();

            var panel = GUI.DeclarePanel()
                .ShowTitle("通讯监控")
                .ForceFloat()
                .InitSize(1400, 800)
                .InitPos(false, 0, 0, 0.5f, 0.5f, 0.5f, 0.5f);
            _panel = panel;
            panel.IfTerminalQuit(() =>
            {
                Unsubscribe();
                _panel = null;
            });

            Subscribe();

            panel.Define(pb =>
            {
                if (pb.Closing())
                {
                    Unsubscribe();
                    panel.Exit();
                    _panel = null;
                    return;
                }

                FlushPendingBatch();

                if (pb.DropdownBox("IP筛选", _ipOptions, ref _selectedIpIndex))
                    ReloadFromService();

                pb.SameLine(16);
                if (pb.Button(_paused ? "继续" : "暂停", distinct: "comm-pause"))
                    _paused = !_paused;
                pb.SameLine(8);
                if (pb.Button("刷新", distinct: "comm-refresh"))
                {
                    RefreshIpFilter();
                    ReloadFromService();
                    RequestStatisticsRefresh();
                }
                pb.SameLine(8);
                if (pb.Button("清空", distinct: "comm-clear"))
                {
                    FairyUiHelper.ConfirmThen("确定要清空所有报文记录吗？", () =>
                    {
                        MessageService.Clear();
                        lock (PendingLock)
                            PendingMessages.Clear();
                        RefreshIpFilter();
                        _displayMessages.Clear();
                        _selectedRowIndex = -1;
                        _parsedText = "";
                        RequestStatisticsRefresh();
                    });
                }
                pb.SameLine(8);
                if (pb.Button("关闭", distinct: "comm-close"))
                {
                    Unsubscribe();
                    panel.Exit();
                    _panel = null;
                    return;
                }

                MaybeRefreshStatistics();
                pb.Label(_statsText);

                pb.Table(TableId,
                    new[] { "时间", "方向", "IP地址", "端口", "长度", "原始数据", "站点", "类型", "操作" },
                    _displayMessages.Count, (row, i) =>
                    {
                        var msg = _displayMessages[i];
                        row.SetColor(_selectedRowIndex == i
                            ? SelectedRowColor
                            : msg.Direction == MessageDirection.Send ? SendRowColor : ReceiveRowColor);

                        row.Label($"{msg.Timestamp:HH:mm:ss.fff}");
                        row.Label(msg.Direction == MessageDirection.Send ? "发送" : "接收");
                        row.Label(msg.IpAddress ?? "");
                        row.Label($"{msg.Port}");
                        row.Label($"{msg.Length}");
                        row.Label(TruncateRawData(msg.RawData));
                        row.Label(string.IsNullOrEmpty(msg.StationId) ? "-" : msg.StationId);
                        row.Label(msg.Type ?? "");

                        if (row.ButtonGroup(new[] { "解析" }, new[] { "解析该报文" }) == 0)
                        {
                            _selectedRowIndex = i;
                            _parsedText = BuildParsedText(msg);
                        }
                    }, height: FairyUiHelper.TableHeightPx(20), enableSearch: true);

                pb.SeparatorText("报文解析");
                pb.SelectableText(null, _parsedText ?? "", copyButton: true);

                pb.Panel.Repaint(repaintTimeMs: 500);
            });
        }

        private void Subscribe()
        {
            if (_subscribed)
                return;
            MessageService.MessageAdded += OnMessageAdded;
            _subscribed = true;
        }

        private void Unsubscribe()
        {
            if (!_subscribed)
                return;
            MessageService.MessageAdded -= OnMessageAdded;
            _subscribed = false;
            lock (PendingLock)
                PendingMessages.Clear();
        }

        private void OnMessageAdded(object sender, CommunicationMessage message)
        {
            if (!_subscribed || message == null)
                return;

            lock (PendingLock)
                PendingMessages.Enqueue(message);

            _panel?.Repaint();
        }

        /// <summary>定时批量刷新 UI，避免每条报文都抢占渲染线程。</summary>
        private void FlushPendingBatch()
        {
            if (_paused)
                return;

            List<CommunicationMessage> batch = null;
            lock (PendingLock)
            {
                if (PendingMessages.Count == 0)
                    return;

                int count = Math.Min(UiBatchSize, PendingMessages.Count);
                batch = new List<CommunicationMessage>(count);
                for (int i = 0; i < count; i++)
                    batch.Add(PendingMessages.Dequeue());
            }

            if (batch == null || batch.Count == 0)
                return;

            var filter = SelectedIpFilter();
            bool displayChanged = false;

            foreach (var message in batch)
            {
                EnsureIpInFilter(message.IpAddress);
                if (string.IsNullOrEmpty(filter) || filter == "全部" || filter == message.IpAddress)
                {
                    InsertMessageAtTop(message);
                    displayChanged = true;
                }
            }

            if (displayChanged)
                RequestStatisticsRefresh();
        }

        private void InsertMessageAtTop(CommunicationMessage msg)
        {
            _displayMessages.Insert(0, msg);
            while (_displayMessages.Count > MaxDisplayRows)
                _displayMessages.RemoveAt(_displayMessages.Count - 1);

            if (_selectedRowIndex >= 0)
                _selectedRowIndex++;
        }

        private void ReloadFromService()
        {
            try
            {
                var filter = SelectedIpFilter();
                var messages = string.IsNullOrEmpty(filter) || filter == "全部"
                    ? MessageService.GetAllMessages()
                    : MessageService.GetMessagesByIp(filter);

                _displayMessages = messages.Take(MaxDisplayRows).ToList();
                _selectedRowIndex = -1;
                _parsedText = "";
                _pendingStatsRefresh = false;
                UpdateStatistics(_displayMessages.Count);
            }
            catch (Exception ex)
            {
                _statsText = $"加载报文失败: {ex.Message}";
            }
        }

        private void RefreshIpFilter()
        {
            try
            {
                var selectedIp = SelectedIpFilter();
                var options = new List<string> { "全部" };

                var ipAddresses = MessageService.GetUniqueIpAddresses();
                if (ipAddresses != null)
                {
                    foreach (var ip in ipAddresses)
                    {
                        if (!string.IsNullOrEmpty(ip))
                            options.Add(ip);
                    }
                }

                _ipOptions = options.ToArray();

                if (!string.IsNullOrEmpty(selectedIp))
                {
                    var idx = Array.IndexOf(_ipOptions, selectedIp);
                    _selectedIpIndex = idx >= 0 ? idx : 0;
                }
                else
                {
                    _selectedIpIndex = 0;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"刷新IP筛选失败: {ex.Message}");
            }
        }

        private void EnsureIpInFilter(string ipAddress)
        {
            if (string.IsNullOrWhiteSpace(ipAddress))
                return;

            if (_ipOptions.Contains(ipAddress))
                return;

            var list = _ipOptions.ToList();
            list.Add(ipAddress);
            _ipOptions = list.ToArray();
        }

        private string SelectedIpFilter()
        {
            if (_ipOptions == null || _ipOptions.Length == 0)
                return "全部";
            if (_selectedIpIndex < 0 || _selectedIpIndex >= _ipOptions.Length)
                return "全部";
            return _ipOptions[_selectedIpIndex];
        }

        private void RequestStatisticsRefresh()
        {
            _pendingStatsRefresh = true;
        }

        /// <summary>统计信息低频刷新（500ms）。</summary>
        private void MaybeRefreshStatistics()
        {
            if (!_pendingStatsRefresh)
                return;
            if (DateTime.Now - _lastStatsRefresh < TimeSpan.FromMilliseconds(StatsRefreshMs))
                return;

            _pendingStatsRefresh = false;
            _lastStatsRefresh = DateTime.Now;
            UpdateStatistics(_displayMessages.Count);
        }

        private void UpdateStatistics(int displayCount)
        {
            try
            {
                var allMessages = MessageService.GetAllMessages();
                if (allMessages == null)
                {
                    _statsText = "统计信息加载失败";
                    return;
                }

                var sendCount = allMessages.Count(m => m.Direction == MessageDirection.Send);
                var receiveCount = allMessages.Count(m => m.Direction == MessageDirection.Receive);
                _statsText = $"显示: {displayCount} | 总数: {allMessages.Count} | 发送: {sendCount} | 接收: {receiveCount}";
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"更新统计信息失败: {ex.Message}");
                _statsText = "统计信息加载失败";
            }
        }

        private string TruncateRawData(string rawData, int maxLen = 48)
        {
            if (string.IsNullOrEmpty(rawData))
                return "";
            return rawData.Length <= maxLen ? rawData : rawData.Substring(0, maxLen) + "…";
        }

        private string BuildParsedText(CommunicationMessage message)
        {
            if (message == null)
                return "";

            try
            {
                var parsed = new StringBuilder();
                parsed.AppendLine("=== 报文解析 ===");
                parsed.AppendLine($"时间: {message.Timestamp:yyyy-MM-dd HH:mm:ss.fff}");
                parsed.AppendLine($"方向: {(message.Direction == MessageDirection.Send ? "发送" : "接收")}");
                parsed.AppendLine($"地址: {message.IpAddress}:{message.Port}");
                parsed.AppendLine($"站点: {message.StationId ?? "未关联"}");
                parsed.AppendLine($"长度: {message.Length} 字节");
                parsed.AppendLine();
                parsed.AppendLine("=== 原始数据 (HEX) ===");
                parsed.AppendLine(message.RawData);
                parsed.AppendLine();
                parsed.AppendLine("=== 数据解析 ===");

                if (message.Direction == MessageDirection.Send)
                {
                    var sendData = MessageService.ParseSendRawData(message.RawData, message.Type);
                    parsed.AppendLine("示例解析：");
                    parsed.AppendLine($"充电指令：{sendData.ChargeCommand}");
                    parsed.AppendLine($"发送电压：{sendData.SetVoltage}");
                    parsed.AppendLine($"发送电流：{sendData.SetCurrent}");
                    parsed.AppendLine($"车辆ID：{sendData.CurrentVehicleId}");
                    parsed.AppendLine($"车辆电量：{sendData.BatteryLevel}");
                    parsed.AppendLine($"车辆电压：{sendData.CarVoltage}");
                    parsed.AppendLine($"车辆电流：{sendData.CarCurrent}");
                }
                else
                {
                    var recData = MessageService.ParseReceiveRawData(message.RawData, message.Type);
                    string mechanismStatus = (int)recData.MechanismStatus == 1 ? "伸出"
                        : (int)recData.MechanismStatus == 2 ? "缩回"
                        : (int)recData.MechanismStatus == 3 ? "运动中"
                        : recData.MechanismStatus.ToString();
                    parsed.AppendLine("示例解析：");
                    parsed.AppendLine($"机构状态：{mechanismStatus}");
                    parsed.AppendLine($"实时电压：{recData.RealTimeVoltage}");
                    parsed.AppendLine($"实时电流：{recData.RealTimeCurrent}");
                    parsed.AppendLine($"充电量： {recData.BatteryAH}");
                    parsed.AppendLine($"是否报警：{recData.HasAlarm}");
                    parsed.AppendLine($"充电状态：{recData.Status}");
                }

                return parsed.ToString();
            }
            catch (Exception ex)
            {
                return $"解析失败: {ex.Message}";
            }
        }
    }
}
