using Model.Models;
using Prism.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UIShare.PubEvent;
using ZLGUSBCANFD;

namespace UIShare.GlobalVariable
{
    /// <summary>
    /// CAN 信号广播器（全局单例）：
    /// 统一订阅 GlobalInfo.CanPool 中所有已实例化的 ZLGCANFD 设备，
    /// 将 DBC 解码后的信号值广播给所有引用该 CAN 设备的作用域，
    /// 并同步检查各作用域 ValueLimitList 的超限报警。
    /// </summary>
    public class CANSignalBroadcaster : IDisposable
    {
        private readonly IEventAggregator _eventAggregator;
        private readonly GlobalInfo _globalInfo;
        private bool _disposed;

        /// <summary>已订阅解码事件的 CANFD 实例 → 委托 映射</summary>
        private readonly Dictionary<ZLGCANFD, Action<uint, ZDBC.DBCMessage>> _handlers = new();

        public CANSignalBroadcaster(GlobalInfo globalInfo, IEventAggregator eventAggregator)
        {
            _globalInfo = globalInfo;
            _eventAggregator = eventAggregator;
        }

        /// <summary>
        /// 扫描 GlobalInfo.CanPool 中已创建的 CANFD 实例并订阅解码事件。
        /// 幂等：已订阅的实例不会重复订阅。
        /// </summary>
        public void Discover()
        {
            if (_disposed) return;

            foreach (var kvp in _globalInfo.CanPool)
            {
                string fingerprint = kvp.Key;
                var lazy = kvp.Value;
                if (!lazy.IsValueCreated || lazy.Value == null) continue;

                var canfd = lazy.Value;
                if (_handlers.ContainsKey(canfd)) continue;

                // 使用闭包捕获指纹，回调时即可区分不同 CAN 卡
                Action<uint, ZDBC.DBCMessage> handler = (channel, msg) => OnDbcMessageDecoded(fingerprint, channel, msg);
                canfd.OnDbcMessageDecoded += handler;
                _handlers[canfd] = handler;
            }
        }

        /// <summary>
        /// 启动广播器（目前 Discover 已完成订阅，此处保留以兼容 HardwareDataBroadcaster 的使用模式）。
        /// </summary>
        public void Start()
        {
            Discover();
        }

        /// <summary>
        /// DBC 解码回调：提取所有信号，向引用该 CAN 设备的作用域广播，并检查报警。
        /// </summary>
        private void OnDbcMessageDecoded(string canFingerprint, uint channel, ZDBC.DBCMessage msg)
        {
            if (_disposed) return;

            string signalFingerprint = BuildFingerprint(canFingerprint, channel);
            var now = DateTime.Now;

            // 获取引用该 CAN 设备的所有作用域
            var scopes = GetScopesForFingerprint(canFingerprint);
            if (scopes.Count == 0) return;

            for (int i = 0; i < msg.nSignalCount; i++)
            {
                var signal = msg.vSignals[i];
                string signalName = Encoding.Default.GetString(signal.strName).TrimEnd('\0');
                if (string.IsNullOrEmpty(signalName)) continue;

                double physicalValue = signal.nRawvalue * signal.nFactor + signal.nOffset;
                string methodName = BuildMethodName(msg.nID, signalName);

                foreach (var scope in scopes)
                {
                    _eventAggregator.GetEvent<HardwareDataReportedEvent>().Publish(new HardwareReportArgs
                    {
                        Scope = scope,
                        HardwareFingerprint = signalFingerprint,
                        MethodName = methodName,
                        Value = physicalValue,
                        Time = now
                    });

                    string MonitorStatus = ValueLimitAlarmHelper.CheckAlarm(scope, signalFingerprint, methodName, physicalValue, _globalInfo);
                    if (MonitorStatus != "" && MonitorStatus != "未报警")
                    {
                        _eventAggregator.GetEvent<AlarmEvent>().Publish((scope,canFingerprint, MonitorStatus));
                    }
                }
            }
        }

        /// <summary>获取指定硬件指纹当前被哪些作用域引用</summary>
        private List<string> GetScopesForFingerprint(string fingerprint)
        {
            if (_globalInfo.DeviceAndScopeDic.TryGetValue(fingerprint, out var lazy))
            {
                var scopeList = lazy.Value;
                lock (scopeList) return scopeList.ToList();
            }
            return new List<string>();
        }

        /// <summary>
        /// 生成 CAN 信号的 DisplayName 格式："{MessageName}.{SignalName}"
        /// </summary>
        public static string BuildDisplayName(string messageName, string signalName)
        {
            return $"{messageName}.{signalName}";
        }

        /// <summary>
        /// 生成 CAN 信号的 MethodName 格式："{MessageId:X}.{SignalName}"
        /// </summary>
        public static string BuildMethodName(uint messageId, string signalName)
        {
            return $"{messageId:X}.{signalName}";
        }

        /// <summary>
        /// 生成 CAN 信号的 Fingerprint 格式："{canDeviceFingerprint}:{channel}"
        /// canDeviceFingerprint 来自 DeviceManager.ExtractHardwareFingerprint，如 "CAN:0"
        /// </summary>
        public static string BuildFingerprint(string canDeviceFingerprint, uint channel)
        {
            return $"{canDeviceFingerprint}:{channel}";
        }

        public void Dispose()
        {
            if (_disposed) return;
            _disposed = true;

            foreach (var kvp in _handlers)
            {
                if (kvp.Key != null)
                    kvp.Key.OnDbcMessageDecoded -= kvp.Value;
            }
            _handlers.Clear();
        }
    }
}
