using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Threading;
using System.Windows.Data;
using NavisworksTransport.Core;

namespace NavisworksTransport.UI.WPF.Collections
{
    /// <summary>
    /// 线程安全的ObservableCollection实现
    /// 专门为WPF数据绑定场景设计，支持跨线程操作和批量更新
    /// 
    /// 主要特性：
    /// 1. 线程安全的集合操作，防止并发修改异常
    /// 2. 自动UI线程同步，确保PropertyChanged和CollectionChanged事件在UI线程触发
    /// 3. 批量操作优化，减少UI更新频率
    /// 4. 集成UIStateManager进行统一的线程安全管理
    /// </summary>
    /// <typeparam name="T">集合元素类型</typeparam>
    public class ThreadSafeObservableCollection<T> : ObservableCollection<T>
    {
        #region 字段和属性

        private readonly object _lock = new object();
        private readonly SynchronizationContext _synchronizationContext;
        private volatile bool _suppressNotification = false;

        /// <summary>
        /// 获取当前是否正在批量更新中（禁用通知）
        /// </summary>
        public bool IsBatchUpdating => _suppressNotification;

        /// <summary>
        /// 获取当前集合元素数量（线程安全）
        /// </summary>
        public new int Count
        {
            get
            {
                lock (_lock)
                {
                    return base.Count;
                }
            }
        }

        #endregion

        #region 构造函数

        /// <summary>
        /// 初始化线程安全的ObservableCollection
        /// </summary>
        public ThreadSafeObservableCollection()
            : base()
        {
            _synchronizationContext = SynchronizationContext.Current;

            // 启用WPF集合同步机制
            BindingOperations.EnableCollectionSynchronization(this, _lock);

            LogManager.Debug($"ThreadSafeObservableCollection<{typeof(T).Name}>已初始化");
        }

        /// <summary>
        /// 使用指定的初始元素初始化线程安全的ObservableCollection
        /// </summary>
        /// <param name="collection">初始元素集合</param>
        public ThreadSafeObservableCollection(IEnumerable<T> collection)
            : base(collection)
        {
            _synchronizationContext = SynchronizationContext.Current;

            // 启用WPF集合同步机制
            BindingOperations.EnableCollectionSynchronization(this, _lock);

            LogManager.Debug($"ThreadSafeObservableCollection<{typeof(T).Name}>已初始化，包含{Count}个元素");
        }

        #endregion

        #region 基础集合操作重写

        /// <summary>
        /// 线程安全的添加元素
        /// </summary>
        /// <param name="item">要添加的元素</param>
        public new void Add(T item)
        {
            if (item == null)
            {
                throw new ArgumentNullException(nameof(item));
            }

            lock (_lock)
            {
                base.Add(item);
            }
        }

        /// <summary>
        /// 线程安全的插入元素
        /// </summary>
        /// <param name="index">插入位置</param>
        /// <param name="item">要插入的元素</param>
        public new void Insert(int index, T item)
        {
            if (item == null)
            {
                throw new ArgumentNullException(nameof(item));
            }

            lock (_lock)
            {
                base.Insert(index, item);
            }
        }

        /// <summary>
        /// 线程安全的移除元素
        /// </summary>
        /// <param name="item">要移除的元素</param>
        /// <returns>是否成功移除</returns>
        public new bool Remove(T item)
        {
            lock (_lock)
            {
                return base.Remove(item);
            }
        }

        /// <summary>
        /// 线程安全的移除指定位置的元素
        /// </summary>
        /// <param name="index">要移除的元素位置</param>
        public new void RemoveAt(int index)
        {
            lock (_lock)
            {
                base.RemoveAt(index);
            }
        }

        /// <summary>
        /// 线程安全的清空集合
        /// </summary>
        public new void Clear()
        {
            lock (_lock)
            {
                base.Clear();
            }
        }

        /// <summary>
        /// 线程安全的元素访问
        /// </summary>
        /// <param name="index">元素索引</param>
        /// <returns>指定位置的元素</returns>
        public new T this[int index]
        {
            get
            {
                lock (_lock)
                {
                    return base[index];
                }
            }
            set
            {
                lock (_lock)
                {
                    base[index] = value;
                }
            }
        }

        #endregion

        #region 批量操作接口

        /// <summary>
        /// 批量添加元素（原子操作）
        /// 所有元素添加完成后才触发一次CollectionChanged事件
        /// </summary>
        /// <param name="items">要添加的元素集合</param>
        public void AddRange(IEnumerable<T> items)
        {
            if (items == null)
            {
                throw new ArgumentNullException(nameof(items));
            }

            var itemList = items.ToList();
            if (itemList.Count == 0)
            {
                return;
            }

            lock (_lock)
            {
                try
                {
                    // 禁用通知
                    _suppressNotification = true;

                    // 批量添加
                    foreach (var item in itemList)
                    {
                        if (item != null)
                        {
                            base.Add(item);
                        }
                    }
                }
                finally
                {
                    // 恢复通知
                    _suppressNotification = false;
                }

                // 触发批量添加事件
                OnCollectionChanged(new NotifyCollectionChangedEventArgs(
                    NotifyCollectionChangedAction.Add,
                    itemList,
                    Count - itemList.Count));
            }

            LogManager.Debug($"ThreadSafeObservableCollection批量添加{itemList.Count}个元素");
        }

        /// <summary>
        /// 批量移除元素（原子操作）
        /// </summary>
        /// <param name="items">要移除的元素集合</param>
        /// <returns>实际移除的元素数量</returns>
        public int RemoveRange(IEnumerable<T> items)
        {
            if (items == null)
            {
                throw new ArgumentNullException(nameof(items));
            }

            var itemList = items.ToList();
            if (itemList.Count == 0)
            {
                return 0;
            }

            var removedItems = new List<T>();

            lock (_lock)
            {
                try
                {
                    // 禁用通知
                    _suppressNotification = true;

                    // 批量移除
                    foreach (var item in itemList)
                    {
                        if (base.Remove(item))
                        {
                            removedItems.Add(item);
                        }
                    }
                }
                finally
                {
                    // 恢复通知
                    _suppressNotification = false;
                }

                // 如果有元素被移除，触发批量移除事件
                if (removedItems.Count > 0)
                {
                    OnCollectionChanged(new NotifyCollectionChangedEventArgs(
                        NotifyCollectionChangedAction.Remove, 
                        removedItems));
                }
            }

            LogManager.Debug($"ThreadSafeObservableCollection批量移除{removedItems.Count}个元素");
            return removedItems.Count;
        }

        /// <summary>
        /// 清空并批量添加元素（原子操作）
        /// 等效于先Clear()再AddRange()，但只触发一次Reset事件
        /// </summary>
        /// <param name="items">新的元素集合</param>
        public void ClearAndAddRange(IEnumerable<T> items)
        {
            if (items == null)
            {
                throw new ArgumentNullException(nameof(items));
            }

            var itemList = items.ToList();

            lock (_lock)
            {
                try
                {
                    // 禁用通知
                    _suppressNotification = true;

                    // 清空现有元素
                    base.Clear();

                    // 添加新元素
                    foreach (var item in itemList)
                    {
                        if (item != null)
                        {
                            base.Add(item);
                        }
                    }
                }
                finally
                {
                    // 恢复通知
                    _suppressNotification = false;
                }

                // 触发重置事件
                OnCollectionChanged(new NotifyCollectionChangedEventArgs(
                    NotifyCollectionChangedAction.Reset));
            }

            LogManager.Debug($"ThreadSafeObservableCollection重置并添加{itemList.Count}个元素");
        }

        /// <summary>
        /// 批量更新操作的安全执行方法
        /// 在指定的操作期间禁用集合变更通知，操作完成后触发Reset事件
        /// </summary>
        /// <param name="batchOperation">批量操作委托</param>
        public void ExecuteBatchUpdate(Action<ThreadSafeObservableCollection<T>> batchOperation)
        {
            if (batchOperation == null)
            {
                throw new ArgumentNullException(nameof(batchOperation));
            }

            lock (_lock)
            {
                try
                {
                    // 禁用通知
                    _suppressNotification = true;

                    // 执行批量操作
                    batchOperation(this);
                }
                finally
                {
                    // 恢复通知
                    _suppressNotification = false;
                }

                // 触发重置事件，通知UI重新绑定
                OnCollectionChanged(new NotifyCollectionChangedEventArgs(
                    NotifyCollectionChangedAction.Reset));
            }

            LogManager.Debug("ThreadSafeObservableCollection批量更新操作完成");
        }

        #endregion

        #region 事件处理重写

        /// <summary>
        /// 重写集合变更事件处理，确保在UI线程中触发
        /// </summary>
        /// <param name="e">集合变更事件参数</param>
        protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            // 如果正在批量更新，跳过通知
            if (_suppressNotification)
            {
                return;
            }

            try
            {
                // 如果当前在UI线程，直接触发事件
                if (UIStateManager.Instance.IsUIThread)
                {
                    base.OnCollectionChanged(e);
                }
                else
                {
                    // 异步切换到UI线程触发事件
                    UIStateManager.Instance.QueueUIUpdate(() =>
                    {
                        try
                        {
                            base.OnCollectionChanged(e);
                        }
                        catch (Exception ex)
                        {
                            LogManager.Error($"ThreadSafeObservableCollection事件通知失败: {ex.Message}");
                        }
                    });
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"ThreadSafeObservableCollection OnCollectionChanged异常: {ex.Message}");
                
                // 关键异常，直接抛出
                throw;
            }
        }

        /// <summary>
        /// 重写属性变更事件处理，确保在UI线程中触发
        /// </summary>
        /// <param name="e">属性变更事件参数</param>
        protected override void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            try
            {
                // 如果当前在UI线程，直接触发事件
                if (UIStateManager.Instance.IsUIThread)
                {
                    base.OnPropertyChanged(e);
                }
                else
                {
                    // 异步切换到UI线程触发事件
                    UIStateManager.Instance.QueueUIUpdate(() =>
                    {
                        try
                        {
                            base.OnPropertyChanged(e);
                        }
                        catch (Exception ex)
                        {
                            LogManager.Error($"ThreadSafeObservableCollection属性变更通知失败: {ex.Message}");
                        }
                    });
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"ThreadSafeObservableCollection OnPropertyChanged异常: {ex.Message}");
                
                // 非关键异常，记录但不抛出
            }
        }

        #endregion

        #region 线程安全的查询操作

        /// <summary>
        /// 线程安全的包含性检查
        /// </summary>
        /// <param name="item">要检查的元素</param>
        /// <returns>集合是否包含指定元素</returns>
        public new bool Contains(T item)
        {
            lock (_lock)
            {
                return base.Contains(item);
            }
        }

        /// <summary>
        /// 线程安全的索引查找
        /// </summary>
        /// <param name="item">要查找的元素</param>
        /// <returns>元素的索引，如果不存在返回-1</returns>
        public new int IndexOf(T item)
        {
            lock (_lock)
            {
                return base.IndexOf(item);
            }
        }

        /// <summary>
        /// 线程安全的元素复制
        /// </summary>
        /// <param name="array">目标数组</param>
        /// <param name="arrayIndex">起始索引</param>
        public new void CopyTo(T[] array, int arrayIndex)
        {
            lock (_lock)
            {
                base.CopyTo(array, arrayIndex);
            }
        }

        /// <summary>
        /// 线程安全的枚举器获取
        /// 注意：枚举期间建议避免修改集合
        /// </summary>
        /// <returns>线程安全的枚举器</returns>
        public new IEnumerator<T> GetEnumerator()
        {
            lock (_lock)
            {
                // 创建当前集合的快照用于枚举
                var snapshot = this.ToList();
                return snapshot.GetEnumerator();
            }
        }

        /// <summary>
        /// 获取集合的线程安全快照
        /// </summary>
        /// <returns>当前集合内容的快照列表</returns>
        public List<T> ToSnapshot()
        {
            lock (_lock)
            {
                return this.ToList();
            }
        }

        #endregion

        #region 实用工具方法

        /// <summary>
        /// 线程安全的条件查找
        /// </summary>
        /// <param name="predicate">查找条件</param>
        /// <returns>第一个满足条件的元素，如果不存在返回default(T)</returns>
        public T FirstOrDefault(Func<T, bool> predicate)
        {
            if (predicate == null)
            {
                throw new ArgumentNullException(nameof(predicate));
            }

            lock (_lock)
            {
                return this.Where(predicate).FirstOrDefault();
            }
        }

        /// <summary>
        /// 线程安全的条件计数
        /// </summary>
        /// <param name="predicate">计数条件</param>
        /// <returns>满足条件的元素数量</returns>
        public int CountWhere(Func<T, bool> predicate)
        {
            if (predicate == null)
            {
                throw new ArgumentNullException(nameof(predicate));
            }

            lock (_lock)
            {
                return this.AsEnumerable().Where(predicate).Count();
            }
        }

        /// <summary>
        /// 线程安全的条件存在性检查
        /// </summary>
        /// <param name="predicate">检查条件</param>
        /// <returns>是否存在满足条件的元素</returns>
        public bool Any(Func<T, bool> predicate)
        {
            if (predicate == null)
            {
                throw new ArgumentNullException(nameof(predicate));
            }

            lock (_lock)
            {
                return this.Where(predicate).Any();
            }
        }

        /// <summary>
        /// 线程安全的条件过滤
        /// </summary>
        /// <param name="predicate">过滤条件</param>
        /// <returns>满足条件的元素列表</returns>
        public List<T> Where(Func<T, bool> predicate)
        {
            if (predicate == null)
            {
                throw new ArgumentNullException(nameof(predicate));
            }

            lock (_lock)
            {
                return this.AsEnumerable().Where(predicate).ToList();
            }
        }

        #endregion
    }
}