using NetMQ;
using NetMQ.Sockets;
using SHH.Contracts; // 引用你 ExportCode_Dump2.txt 里的契约

namespace SHH.CameraDashboard
{
    /// <summary>
    /// 视频推流接收服务 (服务端模式)
    /// 职责：监听本地端口，被动接收来自采集端的 Push 数据流
    /// </summary>
    public class VideoPushServer : IDisposable
    {
        private PullSocket? _pullSocket;
        private bool _isRunning;
        private Task? _listenTask;

        // 当收到完整视频帧时触发，UI 层订阅此事件来更新画面
        // VideoPayload 定义在 ExportCode_Dump2.txt 中
        public event Action<VideoPayload>? OnFrameReceived;

        /// <summary>
        /// 启动监听
        /// </summary>
        /// <param name="port">本机开放的监听端口 (例如 6000)</param>
        public void Start(int port)
        {
            if (_isRunning) return;

            try
            {
                _pullSocket = new PullSocket();

                // 1. 设置高水位 (HWM)，防止渲染不及导致内存溢出
                // 与发送端 ForwarderClient 的 HWM_LIMIT = 50 保持策略一致
                _pullSocket.Options.ReceiveHighWatermark = 50;

                // 2. 【核心】绑定本地端口 (Bind)，等待别人连我
                // 允许局域网内任何 IP 推送数据过来
                _pullSocket.Bind($"tcp://*:{port}");

                _isRunning = true;

                // 3. 开启后台接收线程
                _listenTask = Task.Run(ReceiveLoop);

                System.Diagnostics.Debug.WriteLine($"[PushServer] 服务已启动，正在监听端口: {port}...");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"[PushServer] 启动失败: {ex.Message}");
            }
        }

        private void ReceiveLoop()
        {
            while (_isRunning && _pullSocket != null)
            {
                try
                {
                    // 1. 接收多帧消息 (超时控制以便能优雅退出)
                    NetMQMessage? msg = null;
                    if (!_pullSocket.TryReceiveMultipartMessage(TimeSpan.FromMilliseconds(500), ref msg))
                    {
                        continue;
                    }

                    // 2. 协议校验：必须包含 3 帧 (JSON + Raw + Target)
                    // 对应 ExportCode_Dump1.txt 中 ForwarderClient.Push 的 msg.Append 顺序
                    if (msg == null || msg.FrameCount < 3) continue;

                    // 3. 解析数据帧
                    string jsonMeta = msg[0].ConvertToString();
                    byte[] originalBytes = msg[1].Buffer;
                    byte[] targetBytes = msg[2].Buffer;

                    // 4. 反序列化元数据
                    // 使用你 Core/JsonHelper.cs 里的稳健反序列化
                    var payload = JsonHelper.Deserialize<VideoPayload>(jsonMeta);

                    if (payload != null)
                    {
                        // 5. 组装二进制数据 (因为传输时是分离的)
                        payload.OriginalImageBytes = originalBytes;
                        payload.TargetImageBytes = targetBytes;

                        // 6. 触发事件 (抛出给 ViewModel)
                        OnFrameReceived?.Invoke(payload);
                    }
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine($"[PushServer] 接收异常: {ex.Message}");
                }
            }
        }

        public void Stop()
        {
            _isRunning = false;
            _pullSocket?.Close();
            _pullSocket?.Dispose();
            _pullSocket = null;
        }

        public void Dispose()
        {
            Stop();
        }
    }
}