using MessagePack;
using SHH.Contracts;
using SHH.ProcessLaunchers;
using System.Collections.ObjectModel;
using System.Windows;

namespace SHH.CameraDashboard
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        #region 定义全局单例

        /// <summary>
        /// 进程管理器
        /// </summary>
        public static ProcessManager ProcManager { get; private set; }
            = new ProcessManager(new ProcessDashboardLogger());

        #endregion

        #region OnExit

        /// <summary>
        /// 退出时执行
        /// </summary>
        /// <param name="e"></param>
        protected override void OnExit(ExitEventArgs e)
        {
            // 1. 显式停止通讯总线
            CommandBusClient.Instance.Stop();

            // 2. 如果你有其他的单例服务需要清理（比如视频解码库），也放在这里
            base.OnExit(e);

            // 3. 终极保底：如果程序在清理逻辑执行后 3 秒还没消失，强制杀掉进程
            // 防止某些第三方 DLL（如海康 SDK）的线程卡死
            Task.Delay(3000).ContinueWith(_ =>
            {
                System.Diagnostics.Process.GetCurrentProcess().Kill();
            });
        }

        #endregion

        protected override async void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            // 启动视频流接收 (Port 6002)
            StreamReceiverService.Instance.Start(6002);

            // 启动指令服务 (Port 6001)

            CommandBusClient.Instance.Start(6001);
            CommandBusClient.Instance.OnServerRegistered += SetupAutomaticConfiguration;

            //CommandServer.Instance.Start(6001);

            //CommandServer.Instance.OnClientRegistered += SetupAutomaticConfiguration;

            // 现在我们来配置启动

            // 1. 【核心代码】程序启动时，异步读取配置文件
            var savedNodes = await LocalStorageService.LoadAsync<ObservableCollection<ServiceNodeModel>>(AppPaths.ServiceNodesConfig);
            if (savedNodes != null)
            {
                foreach (var node in savedNodes)
                    AppGlobal.ServiceNodes.Add(node);
            }

            // =========================================================
            // 3. 构建启动参数 & 注册进程
            // =========================================================

            // A. 获取当前 Dashboard 的 PID (用于父进程守护)
            int myPid = System.Environment.ProcessId;

            // B. 构建参数字符串
            // --pid: 让 Service 知道谁是父进程
            // --uris: 告诉 Service 反向连接的目标 (注意顺序：视频端口, 指令端口)
            // --mode: 1 (主动连接模式)
            // --ports: Service 自身的 WebAPI 端口 (5005)
            string serviceArgs = $"" +
                $"--pid {myPid} " +
                $"--appid \"CameraApp_01\" " +
                $"--uris \"127.0.0.1,6003,video,调试PC;\" " +
                $"--uris \"127.0.0.1,6001,command,调试PC;\" " +
                $"--uris \"127.0.0.1,6004,command,调试PC;\" " +
                $"--uris \"127.0.0.1,6002,video,大屏展示;\" " +
                $"--mode 1 " +
                $"--ports \"5000,100\"";

            // C. 注册进程配置 (复用 ProcManager)
            ProcManager.Register(new ProcessConfig
            {
                Id = "CameraService",           // 内部标识
                DisplayName = "视频接入服务",     // UI显示名称
                // 请确保路径正确，建议用相对路径 AppDomain.CurrentDomain.BaseDirectory + "SHH.CameraService.exe"
                ExePath = @"D:\Codes\Codes2026\Ayay\SHH.CameraService\bin\Debug\net8.0\SHH.CameraService.exe",
                Arguments = serviceArgs,        // ★★★ 核心：注入参数 ★★★
                StartupOrder = 1,               // 优先级
                RestartDelayMs = 2000,          // 崩溃后2秒重启
                Visible = true,                 // 不显示黑框
                EnableLogRedirect = false,
            });

            // =========================================================
            // 4. 发射！启动所有注册的进程
            // =========================================================
            _ = ProcManager.StartAllAsync();

            // 3. 启动主窗口
            // 注意：如果 LoadAsync 耗时较长，这里可能会导致启动画面停留，
            // 实际项目中可以搞一个 Splash Screen (启动屏) 来做这件事。
            var mainWin = new MainWindow();
            mainWin.Show();
        }

        private void SetupAutomaticConfiguration(RegisterPayload client)
        {
            Console.WriteLine($"[自动化] 新服务上线: {client.InstanceId}");

            //Task.Run(async () =>
            //{
            //    await Task.Delay(500);

            //    // 1. 构建业务配置对象
            //    var cameraConfig = new CameraConfigDto
            //    {
            //        Id = 17798,
            //        Name = "206摄像头",
            //        Location = "404办公室",
            //        IpAddress = "172.16.41.88",
            //        Username = "admin",
            //        Password = "abcd1234",
            //        Port = 8000,
            //        ChannelIndex = 1,
            //        StreamType = 0,
            //        Brand = DeviceBrand.HikVision.GetHashCode(),    // 对应 DeviceBrand 枚举
            //        RenderHandle = 0,          // 初始化为0
            //        MainboardIp = "",          // 留空
            //        MainboardPort = 0,
            //        RtspPath = ""
            //    };

            //    // ★ 新增：一并带上订阅要求 ★
            //    cameraConfig.AutoSubscriptions = new List<CameraConfigSubscribeDto>
            //        {
            //            // 第一条：显示帧，要求 8 帧
            //            new CameraConfigSubscribeDto {
            //                AppId = "UI_Display",
            //                Type = 0,
            //                TargetFps = 8,
            //                Memo = "显示帧"
            //            },
            //            // 第二条：分析帧，要求 1 帧
            //            new CameraConfigSubscribeDto {
            //                AppId = "AI_Analysis",
            //                Type = 0,
            //                Memo = "分析帧",
            //                TargetFps = 1
            //            }
            //        };

            //    // 2. 构造指令包
            //    var command = new CommandPayload
            //    {
            //        Protocol = ProtocolHeaders.Command,
            //        CmdCode = ProtocolHeaders.SyncCamera,
            //        TargetId = client.InstanceId,
            //        RequestId = Guid.NewGuid().ToString("N"),

            //        // ★ 修正 1: 使用 JsonParams 属性名，并将对象序列化为 JSON 字符串 ★
            //        // 因为你的 DTO 定义 JsonParams 是 string 类型
            //        JsonParams = JsonHelper.Serialize(cameraConfig),

            //        // ★ 修正 2: Timestamp 直接赋值 DateTime 对象 ★
            //        // 因为你的 DTO 定义 Timestamp 是 DateTime 类型
            //        Timestamp = DateTime.Now,

            //        RequireAck = true
            //    };

            //    // 3. 发送
            //    await CommandBusClient.Instance.SendInternalAsync(client.InstanceId, command);
            //});
        }

        /// <summary>
        /// 全局统一退出入口
        /// </summary>
        public static void ShutdownApp()
        {
            // 1. 这里可以处理统一的资源清理逻辑 (如停止摄像头推流、关闭数据库连接)
            // 2. 保存用户配置
            // 3. 彻底退出
            StreamReceiverService.Instance.Dispose();
            CommandServer.Instance.Dispose();
            // 停止所有子进程
            ProcManager.StopAll();

            Current.Shutdown();
        }

    }
}