using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Threading; // 引入 DispatcherTimer 命名空间

namespace SHH.CameraDashboard
{
    public class CameraListViewModel : INotifyPropertyChanged
    {
        // 存储从 API 获取的所有原始数据
        private readonly ObservableCollection<WebApiCameraModel> _allCameras;

        // 提供给界面绑定的视图 (支持搜索过滤)
        public ICollectionView FilteredCameras { get; private set; }

        #region --- 状态属性 ---

        private bool _isLoading;
        public bool IsLoading
        {
            get => _isLoading;
            set { _isLoading = value; OnPropertyChanged(nameof(IsLoading)); }
        }

        private WebApiCameraModel _selectedCamera;
        public WebApiCameraModel SelectedCamera
        {
            get => _selectedCamera;
            set { _selectedCamera = value; OnPropertyChanged(nameof(SelectedCamera)); }
        }

        private string _searchText;
        public string SearchText
        {
            get => _searchText;
            set
            {
                _searchText = value;
                OnPropertyChanged(nameof(SearchText));
                // 输入文字时立即触发过滤
                FilteredCameras.Refresh();
            }
        }

        #endregion

        #region --- 下拉框节点选择 ---

        // 下拉框的数据源
        public ObservableCollection<ServiceNodeModel> NodeOptions
            => AppGlobal.ServiceNodes;

        private ServiceNodeModel _selectedNode;
        public ServiceNodeModel SelectedNode
        {
            get => _selectedNode;
            set
            {
                if (_selectedNode != value)
                {
                    _selectedNode = value;
                    OnPropertyChanged(nameof(SelectedNode));

                    AppGlobal.UseServiceNode = value;

                    // 切换节点时，自动重新加载数据
                    _ = LoadDataAsync();
                }
            }
        }

        #endregion

        public ICommand RefreshCommand { get; }

        public CameraListViewModel()
        {
            _allCameras = new ObservableCollection<WebApiCameraModel>();

            // 初始化 CollectionView
            FilteredCameras = CollectionViewSource.GetDefaultView(_allCameras);
            FilteredCameras.Filter = FilterCameras;

            AddCameraCommand = new RelayCommand(ExecuteAddCamera);
            DeleteCommand = new RelayCommand(ExecuteDelete);

            RefreshCommand = new RelayCommand<object>(async _ => await LoadDataAsync());

            // --- 新增：定时器 ---
            // 使用 DispatcherTimer 确保在 UI 线程执行，避免跨线程操作集合报错
            var timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(2); // 这里设置间隔，例如 2 秒
            timer.Tick += async (s, e) => await LoadDataAsync();
            timer.Start();
        }

        /// <summary>
        /// 核心：加载数据逻辑 (无刷版本)
        /// </summary>
        public async Task LoadDataAsync()
        {
            // 如果正在加载中，跳过本次（防止并发）
            if (IsLoading) return;

            try
            {
                // 【改动1】只有第一次加载（列表为空）时才显示 Loading 转圈
                // 这样定时刷新时，界面就不会弹出遮罩层
                if (_allCameras.Count == 0) IsLoading = true;

                // 确定要查询的目标节点列表
                var targetNodes = new List<ServiceNodeModel>();

                if (SelectedNode == null || SelectedNode.ServiceNodeIp == "ALL")
                {
                    if (AppGlobal.ServiceNodes != null)
                        targetNodes.AddRange(AppGlobal.ServiceNodes);
                }
                else
                {
                    targetNodes.Add(SelectedNode);
                }

                if (targetNodes.Count == 0)
                {
                    // 如果没有节点，清空列表
                    if (_allCameras.Count > 0) _allCameras.Clear();
                    return;
                }

                // 创建并发任务列表
                var tasks = new List<Task<List<WebApiCameraModel>?>>();

                foreach (var node in targetNodes)
                {
                    if (string.IsNullOrWhiteSpace(node.ServiceNodeIp) || string.IsNullOrWhiteSpace(node.ServiceNodePort))
                        continue;

                    tasks.Add(ApiClient.Instance.Cameras.GetListByAddressAsync(node.ServiceNodeIp, node.ServiceNodePort, "左侧列表刷新"));
                }

                var results = await Task.WhenAll(tasks);

                // 【改动2】先将所有新数据收集到一个临时列表中，不要直接操作界面集合
                var newLatestData = new List<WebApiCameraModel>();
                foreach (var list in results)
                {
                    if (list != null)
                    {
                        newLatestData.AddRange(list);
                    }
                }

                // 【改动3】执行无刷更新 (智能合并)
                if (newLatestData.Count > 0)
                    UpdateCollectionNoFlash(newLatestData);
            }
            finally
            {
                IsLoading = false;
            }
        }

        /// <summary>
        /// 辅助方法：比对新旧数据，只更新变化的，实现“无刷”
        /// </summary>
        private void UpdateCollectionNoFlash(List<WebApiCameraModel> newData)
        {
            // 1. 删除：界面上有，但新数据里没有的 (说明设备断开或移除了)
            // 使用 ToList() 避免在遍历时修改集合报错
            var itemsToRemove = _allCameras.Where(old => !newData.Any(n => n.Id == old.Id)).ToList();
            foreach (var item in itemsToRemove)
            {
                _allCameras.Remove(item);
            }

            // 2. 更新或新增
            foreach (var newCam in newData)
            {
                // 尝试在界面列表中找这个 ID
                var oldCam = _allCameras.FirstOrDefault(x => x.Id == newCam.Id);

                if (oldCam != null)
                {
                    // --- [更新] ---
                    // 找到老对象，手动更新它的属性。
                    // 注意：你的 WebApiCameraModel 必须实现了 INotifyPropertyChanged 
                    // 这里的赋值才会让界面文字发生变化，否则界面不动。
                    oldCam.Name = newCam.Name;
                    oldCam.IpAddress = newCam.IpAddress;
                    oldCam.Brand = newCam.Brand;
                    
                    oldCam.Status = newCam.Status;
                    oldCam.IsOnline = newCam.IsOnline;
                    oldCam.IsPhysicalOnline = newCam.IsPhysicalOnline;
                    oldCam.IsRunning = newCam.IsRunning;
                    
                    oldCam.Width = newCam.Width;
                    oldCam.Height = newCam.Height;
                    oldCam.RealFps = newCam.RealFps;
                    oldCam.TotalFrames = newCam.TotalFrames;
                    oldCam.StreamType = newCam.StreamType;

                    // 如果有其他变化的字段（如帧率），继续在这里赋值...
                }
                else
                {
                    // --- [新增] ---
                    // 没找到，说明是新上线的设备，添加到列表
                    _allCameras.Add(newCam);
                }
            }
        }

        /// <summary>
        /// 本地搜索过滤逻辑
        /// </summary>
        private bool FilterCameras(object obj)
        {
            if (obj is WebApiCameraModel camera)
            {
                // 搜索框为空显示所有
                if (string.IsNullOrWhiteSpace(SearchText)) return true;

                string lowerSearch = SearchText.ToLower();

                // 匹配 名称、IP 或 品牌
                return (camera.Name?.ToLower().Contains(lowerSearch) == true) ||
                       (camera.IpAddress?.Contains(lowerSearch) == true) ||
                       (camera.Brand?.ToLower().Contains(lowerSearch) == true);
            }
            return false;
        }

        public ICommand AddCameraCommand { get; }

        private void ExecuteAddCamera(object obj)
        {
            // 简单直接：通知全世界“我要添加摄像头！”
            AppGlobal.RequestAdd();
        }

        // [新增] 删除命令
        public ICommand DeleteCommand { get; }

        private void ExecuteDelete(object obj)
        {
            // 这里的 obj 就是从界面传过来的 WebApiCameraModel
            if (obj is WebApiCameraModel camera)
            {
                AppGlobal.RequestDelete(camera);
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
}