using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
using System.Windows.Input;

namespace SHH.CameraDashboard
{
    /// <summary>
    /// 主窗口的视图模型 (ViewModel)。
    /// 它封装了主窗口的所有业务逻辑、状态和用户交互命令。
    /// 它还作为一个中心协调者，响应全局事件并管理子视图（如右侧编辑面板和蒙板）。
    /// </summary>
    public class MainWindowViewModel : INotifyPropertyChanged, IDisposable
    {
        #region --- 构造函数 ---

        /// <summary>
        /// 初始化 MainWindowViewModel 的新实例。
        /// </summary>
        public MainWindowViewModel()
        {
            #region 窗体控制命令

            // 最小化窗口控制命令
            MinimizeCommand = new RelayCommand<Window>(win =>
            {
                if (win != null)
                {
                    win.WindowState = WindowState.Minimized;
                }
            });

            // 最大化、还原命令
            ToggleMaximizeCommand = new RelayCommand<Window>(win =>
            {
                if (win == null) return;

                if (win.WindowState == WindowState.Maximized)
                {
                    win.WindowState = WindowState.Normal;
                    MaxButtonContent = "⬜";
                }
                else
                {
                    win.WindowState = WindowState.Maximized;
                    MaxButtonContent = "❐";
                }
            });

            // 关闭应用程序命令
            CloseCommand = new RelayCommand<Window>(win =>
            {
                App.ShutdownApp();
            });

            // 窗体置顶
            ToggleTopMostCommand = new RelayCommand<object>(_ => IsTopMost = !IsTopMost);

            #endregion

            #region 其它控制命令

            // 向导功能命令
            OpenWizardCommand = new RelayCommand<object>(_ =>
            {
                var wizardVM = new WizardClientsViewModel();
                ShowOverlay(wizardVM);
            });

            // 更换主题命令
            SwitchThemeCommand = new RelayCommand<string>(themeName =>
            {
                if (!string.IsNullOrEmpty(themeName))
                    ThemeManager.SetTheme(themeName);
            });

            #endregion

            #region 订阅事件

            // 订阅事件
            AppGlobal.OnRequestAddCamera += HandleAddRequest;       // 新增
            AppGlobal.OnRequestEditCamera += HandleEditRequest;     // 编辑
            AppGlobal.OnRequestDeleteCamera += HandleDeleteRequest; // 删除
            AppGlobal.OnRequestPtzCamera += HandlePtzRequest;       // 云台
            AppGlobal.OnRequestImgProc += HandleImgProcRequest;     //订阅图像处理请求
            AppGlobal.OnRequestSubscription += ShowSubscriptionPanel;   // 订阅图像处理请求

            #endregion

            // 打开或折叠日志面板
            ToggleLogPanelCommand = new RelayCommand<object>(_ => IsLogPanelExpanded = !IsLogPanelExpanded);

            // 初始化子 ViewModel
            DiagnosticVM = new ServiceNodesViewModel();
            
            MainContent = new VideoWallViewModel();

            // 启动异步初始化流程
            _ = InitializeAsync();
        }

        #endregion

        #region --- 事件处理 ---

        #region HandleAddRequest

        /// <summary>
        /// 处理添加请求
        /// </summary>
        public void HandleAddRequest()
        {
            // 1. 创建一个新的、空白的 DTO，并提供一些合理的默认值以提升用户体验
            var newDto = new CameraEditInfo
            {
                Id = 0, // 0 表示新增
                Name = "新摄像头",
                IpAddress = "192.168.1.64",
                Brand = 1, // 默认为海康(1) 或你想要的默认值
                Port = 8000,
                Username = "admin",
                Password = "abcd1234",
                ChannelIndex = 1,
                StreamType = 0, // 主码流
                EnhanceImage = false,
                AllowCompress = true,
            };

            // 2. 创建用于编辑的 ViewModel
            var editVm = new CameraEditViewModel(newDto);

            // 3. 监听编辑窗口的关闭请求，以便在操作完成后进行清理和刷新
            editVm.RequestClose += (isSaved, data) =>
            {
                CurrentRightPanelViewModel = null;
                if (isSaved)
                {
                    System.Diagnostics.Debug.WriteLine("新增成功，刷新列表...");
                    AppGlobal.RequestRefresh();
                }
            };

            // 4. 在右侧面板中显示编辑界面
            CurrentRightPanelViewModel = editVm;
        }

        #endregion

        #region HandleEditRequest

        /// <summary>
        /// 处理编辑请求：调用 Repository 获取数据
        /// </summary>
        private async void HandleEditRequest(WebApiCameraModel listModel)
        {
            if (listModel == null) return;

            try
            {
                // 1. 调用 API 客户端获取该摄像头的完整详细信息
                var editModel = await ApiClient.Instance.Cameras.GetCameraDetailsAsync(listModel.Id);

                if (editModel == null)
                {
                    System.Diagnostics.Debug.WriteLine("获取设备详情失败 (Repository返回null)");
                    return;
                }

                // 2. 创建用于编辑的 ViewModel
                var editVm = new CameraEditViewModel(editModel);

                // 3. 监听编辑窗口的关闭请求
                editVm.RequestClose += (isSaved, newConfig) =>
                {
                    CurrentRightPanelViewModel = null;

                    if (isSaved && newConfig != null)
                    {
                        // 这里以后可以调用 Update 方法
                        System.Diagnostics.Debug.WriteLine($"保存成功: {newConfig.Name}");
                        AppGlobal.RequestRefresh();
                    }
                };

                // 4. 在右侧面板中显示编辑界面
                CurrentRightPanelViewModel = editVm;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"HandleEditRequest 异常: {ex.Message}");
            }
        }

        #endregion

        #region HandleDeleteRequest

        /// <summary>
        /// 处理删除请求
        /// </summary>
        private async void HandleDeleteRequest(WebApiCameraModel camera)
        {
            if (camera == null) return;

            // 1. 弹窗确认 (防止误删)
            var result = MessageBox.Show(
                $"确定要删除摄像头 \"{camera.Name}\" 吗？\n此操作不可恢复。",
                "确认删除",
                MessageBoxButton.YesNo,
                MessageBoxImage.Warning);

            if (result != MessageBoxResult.Yes) return;

            bool success = await ApiClient.Instance.Cameras.DeleteCameraAsync(camera.Id);

            if (success)
            {
                // 3. 成功后刷新列表
                System.Diagnostics.Debug.WriteLine($"删除 {camera.Name} 成功，刷新列表...");
                AppGlobal.RequestRefresh();
            }
            else
            {
                MessageBox.Show("删除失败，请检查网络或日志。", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        #endregion

        #region HandlePtzRequest (新增的处理逻辑)

        /// <summary>
        /// [新增] 处理云台控制请求
        /// </summary>
        private void HandlePtzRequest(WebApiCameraModel camera)
        {
            if (camera == null) return;

            try
            {
                // 1. 创建云台控制的 ViewModel
                var ptzVm = new CameraPtzViewModel(camera);

                // 2. 监听关闭事件 (以便点击面板上的关闭按钮时，能收起右侧面板)
                // 注意：我们需要在 CameraPtzViewModel 中定义这个 RequestClose 事件
                ptzVm.RequestClose += () =>
                {
                    CurrentRightPanelViewModel = null;
                };

                // 3. 将右侧面板的内容切换为 云台控制
                CurrentRightPanelViewModel = ptzVm;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"打开云台失败: {ex.Message}");
            }
        }

        #endregion

        private async void HandleImgProcRequest(WebApiCameraModel camera)
        {
            if (camera == null) return;
            try
            {
                // 获取详情 (因为列表模型可能不包含 TargetResolution 等深层字段)
                var detailDto = await ApiClient.Instance.Cameras.GetCameraDetailsAsync(camera.Id);
                if (detailDto == null) return;

                // 创建 VM
                var vm = new CameraImgProcViewModel(camera, detailDto);

                // 处理关闭回调
                vm.RequestClose += () => CurrentRightPanelViewModel = null;

                CurrentRightPanelViewModel = vm;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"打开图像处理失败: {ex.Message}");
            }
        }

        // 2. 添加处理方法 (仿照 HandlePtzRequest 写法)
        private void ShowSubscriptionPanel(WebApiCameraModel camera)
        {
            if (camera == null) return;

            try
            {
                // A. 复用模式：只创建 ViewModel
                var vm = new CameraImageSubscriptionViewModels(camera);

                // B. 复用关闭逻辑：当子页面请求关闭时，清空当前面板对象
                vm.RequestClose += () => CurrentRightPanelViewModel = null;

                // C. 复用显示通道：直接赋值，UI 会自动更新
                CurrentRightPanelViewModel = vm;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"打开订阅面板失败: {ex.Message}");
            }
        }

        #endregion

        #region --- 通用右侧面板控制 ---

        // 这里的类型是 object (或 INotifyPropertyChanged)
        // 它可以存放 CameraEditViewModel，也可以存放 LogViewModel, SettingsViewModel 等
        private object? _currentRightPanelViewModel;
        public object? CurrentRightPanelViewModel
        {
            get => _currentRightPanelViewModel;
            set
            {
                _currentRightPanelViewModel = value;
                OnPropertyChanged();
                // 每次内容变了，通知 Visibility 属性也更新一下
                OnPropertyChanged(nameof(IsRightPanelVisible));
            }
        }

        // 界面绑定的可见性：只要 Content 不为空，就显示面板
        public bool IsRightPanelVisible => _currentRightPanelViewModel != null;

        #endregion

        #region --- 命令 (Commands) ---

        /// <summary>
        /// 获取最小化窗口的命令。
        /// </summary>
        public ICommand MinimizeCommand { get; }

        /// <summary>
        /// 获取切换窗口最大化/还原状态的命令。
        /// </summary>
        public ICommand ToggleMaximizeCommand { get; }

        /// <summary>
        /// 获取关闭应用程序的命令。
        /// </summary>
        public ICommand CloseCommand { get; }

        /// <summary>
        /// 获取打开客户端配置向导的命令。
        /// </summary>
        public ICommand OpenWizardCommand { get; }

        /// <summary>
        /// 获取根据名称切换主题的命令。
        /// </summary>
        public ICommand SwitchThemeCommand { get; }

        /// <summary>
        /// 获取切换窗口置顶状态的命令。
        /// </summary>
        public ICommand ToggleTopMostCommand { get; }

        /// <summary>
        /// 获取展开或折叠日志面板的命令。
        /// </summary>
        public ICommand ToggleLogPanelCommand { get; }

        #endregion

        #region --- 属性 (Properties) ---

        private string _maxButtonContent = "⬜";
        /// <summary>
        /// 获取或设置最大化/还原按钮的显示内容。
        /// </summary>
        public string MaxButtonContent
        {
            get => _maxButtonContent;
            set { _maxButtonContent = value; OnPropertyChanged(); }
        }

        private bool _isTopMost;
        /// <summary>
        /// 获取或设置一个值，该值指示窗口是否应始终显示在其他窗口之上。
        /// </summary>
        public bool IsTopMost
        {
            get => _isTopMost;
            set
            {
                if (_isTopMost != value)
                {
                    _isTopMost = value;
                    OnPropertyChanged(nameof(IsTopMost));
                    OnPropertyChanged(nameof(TopMostTooltip));
                }
            }
        }

        /// <summary>
        /// 获取用于窗口置顶按钮的动态工具提示文本。
        /// </summary>
        public string TopMostTooltip => IsTopMost ? "取消置顶" : "窗口置顶";

        private bool _isLogPanelExpanded = true;
        /// <summary>
        /// 获取或设置一个值，该值指示日志面板是否展开。
        /// </summary>
        public bool IsLogPanelExpanded
        {
            get => _isLogPanelExpanded;
            set
            {
                if (_isLogPanelExpanded != value)
                {
                    _isLogPanelExpanded = value;
                    OnPropertyChanged(nameof(IsLogPanelExpanded));
                }
            }
        }

        /// <summary>
        /// 获取用于服务节点诊断面板的 ViewModel。
        /// </summary>
        public ServiceNodesViewModel DiagnosticVM { get; }

        #endregion

        #region --- 蒙板/覆盖层管理 ---

        private bool _isOverlayVisible;
        /// <summary>
        /// 获取或设置全局蒙板的可见性。
        /// </summary>
        public bool IsOverlayVisible
        {
            get => _isOverlayVisible;
            set { _isOverlayVisible = value; OnPropertyChanged(); }
        }

        private object? _overlayContent;
        /// <summary>
        /// 获取或设置蒙板内显示的内容（一个子 ViewModel）。
        /// </summary>
        public object? OverlayContent
        {
            get => _overlayContent;
            set { _overlayContent = value; OnPropertyChanged(); }
        }

        /// <summary>
        /// 显示一个带有指定内容的全局蒙板。
        /// </summary>
        /// <param name="contentViewModel">要在蒙板中显示的子 ViewModel。</param>
        public void ShowOverlay(object contentViewModel)
        {
            if (contentViewModel == null) return;

            if (contentViewModel is IOverlayClosable closable)
            {
                closable.RequestClose += () =>
                {
                    IsOverlayVisible = false;
                    OverlayContent = null;
                };
            }

            OverlayContent = contentViewModel;
            IsOverlayVisible = true;
        }

        #endregion

        #region --- 辅助方法 ---

        /// <summary>
        /// 执行应用程序的异步初始化逻辑。
        /// </summary>
        private async Task InitializeAsync()
        {
            await Task.Delay(500);

            if (CheckIfNeedWizard())
            {
                var wizardVM = new WizardClientsViewModel();
                ShowOverlay(wizardVM);
            }
        }

        /// <summary>
        /// 检查是否需要在启动时显示设置向导。
        /// </summary>
        private bool CheckIfNeedWizard()
        {
            return true;
        }

        #endregion

        #region --- INotifyPropertyChanged 实现 ---

        /// <summary>
        /// 当属性值更改时发生。
        /// </summary>
        public event PropertyChangedEventHandler? PropertyChanged;

        /// <summary>
        /// 引发 PropertyChanged 事件，通知UI更新。
        /// </summary>
        protected void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string name = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }

        #endregion

        private object _mainContent;
        public object MainContent
        {
            get => _mainContent;
            set { _mainContent = value; OnPropertyChanged(); }
        }

        public void Dispose()
        {
        }
    }
}