using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using NavisworksTransport.UI.WPF.ViewModels;
using NavisworksTransport.UI.WPF.Interfaces;

namespace NavisworksTransport.UI.WPF.Services
{
    /// <summary>
    /// 智能数据绑定优化器 - 提供条件更新、延迟更新和批量更新机制
    /// 通过智能策略优化WPF数据绑定的性能表现
    /// </summary>
    public class SmartDataBindingOptimizer : IDisposable
    {
        #region 字段和属性

        private static SmartDataBindingOptimizer _instance;
        private static readonly object _instanceLock = new object();

        // 延迟更新机制
        private readonly Dictionary<string, DelayedUpdateContext> _delayedUpdates;
        private readonly Timer _delayedUpdateTimer;
        private readonly object _delayedUpdateLock = new object();

        // 批量更新机制
        private readonly Dictionary<object, BatchUpdateContext> _batchUpdates;
        private readonly object _batchUpdateLock = new object();

        // 条件更新机制
        private readonly Dictionary<string, ConditionalUpdateConfig> _conditionalConfigs;
        private readonly object _conditionalConfigLock = new object();

        // 配置选项
        private TimeSpan _defaultDelayInterval = TimeSpan.FromMilliseconds(100);
        private TimeSpan _batchUpdateInterval = TimeSpan.FromMilliseconds(50);
        private int _maxBatchSize = 50;
        private volatile bool _isDisposed = false;

        /// <summary>
        /// 获取智能数据绑定优化器的单例实例
        /// </summary>
        public static SmartDataBindingOptimizer Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (_instanceLock)
                    {
                        if (_instance == null)
                        {
                            _instance = new SmartDataBindingOptimizer();
                        }
                    }
                }
                return _instance;
            }
        }

        /// <summary>
        /// 默认延迟更新间隔
        /// </summary>
        public TimeSpan DefaultDelayInterval
        {
            get => _defaultDelayInterval;
            set => _defaultDelayInterval = value;
        }

        /// <summary>
        /// 批量更新间隔
        /// </summary>
        public TimeSpan BatchUpdateInterval
        {
            get => _batchUpdateInterval;
            set => _batchUpdateInterval = value;
        }

        /// <summary>
        /// 最大批量更新大小
        /// </summary>
        public int MaxBatchSize
        {
            get => _maxBatchSize;
            set => _maxBatchSize = Math.Max(1, value);
        }

        #endregion

        #region 构造函数

        private SmartDataBindingOptimizer()
        {
            _delayedUpdates = new Dictionary<string, DelayedUpdateContext>();
            _batchUpdates = new Dictionary<object, BatchUpdateContext>();
            _conditionalConfigs = new Dictionary<string, ConditionalUpdateConfig>();

            // 初始化延迟更新定时器
            _delayedUpdateTimer = new Timer(ProcessDelayedUpdates, null, _defaultDelayInterval, _defaultDelayInterval);

            LogManager.Info("智能数据绑定优化器已初始化");
        }

        #endregion

        #region 延迟更新机制

        /// <summary>
        /// 注册延迟更新 - 将多个快速连续的属性更新合并为一次更新
        /// </summary>
        /// <param name="target">目标对象</param>
        /// <param name="propertyName">属性名称</param>
        /// <param name="updateAction">更新操作</param>
        /// <param name="delayInterval">延迟间隔，null使用默认值</param>
        public void RegisterDelayedUpdate(INotifyPropertyChanged target, string propertyName, Action updateAction, TimeSpan? delayInterval = null)
        {
            if (_isDisposed || target == null || string.IsNullOrEmpty(propertyName) || updateAction == null)
                return;

            var key = $"{target.GetHashCode()}_{propertyName}";
            var delay = delayInterval ?? _defaultDelayInterval;

            lock (_delayedUpdateLock)
            {
                if (_delayedUpdates.TryGetValue(key, out var existingContext))
                {
                    // 更新现有的延迟更新
                    existingContext.UpdateAction = updateAction;
                    existingContext.ScheduledTime = DateTime.UtcNow.Add(delay);
                    existingContext.UpdateCount++;
                }
                else
                {
                    // 创建新的延迟更新
                    var context = new DelayedUpdateContext
                    {
                        Key = key,
                        Target = new WeakReference(target),
                        PropertyName = propertyName,
                        UpdateAction = updateAction,
                        ScheduledTime = DateTime.UtcNow.Add(delay),
                        UpdateCount = 1
                    };

                    _delayedUpdates[key] = context;
                }
            }
        }

        /// <summary>
        /// 立即执行指定对象的所有延迟更新
        /// </summary>
        /// <param name="target">目标对象</param>
        public void FlushDelayedUpdates(INotifyPropertyChanged target)
        {
            if (_isDisposed || target == null)
                return;

            var targetHash = target.GetHashCode();
            List<DelayedUpdateContext> contextsToExecute;

            lock (_delayedUpdateLock)
            {
                contextsToExecute = _delayedUpdates.Values
                    .Where(c => c.Target.Target == target)
                    .ToList();

                // 从字典中移除这些上下文
                foreach (var context in contextsToExecute)
                {
                    _delayedUpdates.Remove(context.Key);
                }
            }

            // 在锁外执行更新操作
            foreach (var context in contextsToExecute)
            {
                ExecuteDelayedUpdate(context);
            }
        }

        /// <summary>
        /// 处理到期的延迟更新
        /// </summary>
        private void ProcessDelayedUpdates(object state)
        {
            if (_isDisposed)
                return;

            var now = DateTime.UtcNow;
            List<DelayedUpdateContext> updatesToExecute;

            lock (_delayedUpdateLock)
            {
                updatesToExecute = _delayedUpdates.Values
                    .Where(c => c.ScheduledTime <= now)
                    .ToList();

                // 移除即将执行的更新
                foreach (var update in updatesToExecute)
                {
                    _delayedUpdates.Remove(update.Key);
                }

                // 清理失效的弱引用
                var keysToRemove = _delayedUpdates
                    .Where(kvp => !kvp.Value.Target.IsAlive)
                    .Select(kvp => kvp.Key)
                    .ToList();

                foreach (var key in keysToRemove)
                {
                    _delayedUpdates.Remove(key);
                }
            }

            // 在锁外执行更新操作
            foreach (var update in updatesToExecute)
            {
                ExecuteDelayedUpdate(update);
            }
        }

        /// <summary>
        /// 执行延迟更新
        /// </summary>
        private void ExecuteDelayedUpdate(DelayedUpdateContext context)
        {
            try
            {
                var target = context.Target.Target;
                if (target == null)
                    return;

                context.UpdateAction?.Invoke();

                LogManager.Debug($"执行延迟更新: {context.PropertyName}, 合并次数: {context.UpdateCount}");
            }
            catch (Exception ex)
            {
                LogManager.Error($"执行延迟更新失败 {context.PropertyName}: {ex.Message}");
            }
        }

        #endregion

        #region 批量更新机制

        /// <summary>
        /// 开始批量更新 - 在指定作用域内抑制属性变更通知，最后统一触发
        /// </summary>
        /// <param name="target">目标对象</param>
        /// <returns>批量更新上下文</returns>
        public IBatchUpdateScope BeginBatchUpdate(INotifyPropertyChanged target)
        {
            if (_isDisposed || target == null)
                return new EmptyBatchScope();

            lock (_batchUpdateLock)
            {
                if (_batchUpdates.TryGetValue(target, out var existingContext))
                {
                    // 增加引用计数
                    existingContext.ReferenceCount++;
                    return new BatchUpdateScope(this, target, false);
                }
                else
                {
                    // 创建新的批量更新上下文
                    var context = new BatchUpdateContext
                    {
                        Target = target,
                        StartTime = DateTime.UtcNow,
                        ReferenceCount = 1,
                        PropertyChanges = new HashSet<string>()
                    };

                    _batchUpdates[target] = context;
                    return new BatchUpdateScope(this, target, true);
                }
            }
        }

        /// <summary>
        /// 启用智能批处理模式 - 自动检测合适的批处理时机
        /// </summary>
        /// <param name="target">目标对象</param>
        /// <param name="enableAutoDetection">是否启用自动检测</param>
        /// <returns>批处理范围</returns>
        public IBatchUpdateScope EnableSmartBatching(INotifyPropertyChanged target, bool enableAutoDetection = true)
        {
            if (_isDisposed || target == null)
                return new EmptyBatchScope();

            // 如果启用了自动检测，则分析最佳批处理策略
            if (enableAutoDetection)
            {
                var strategy = AnalyzeBatchingStrategy(target);
                return ApplyBatchingStrategy(target, strategy);
            }
            
            // 否则使用标准批处理
            return BeginBatchUpdate(target);
        }

        /// <summary>
        /// 分析最佳批处理策略
        /// </summary>
        private BatchingStrategy AnalyzeBatchingStrategy(INotifyPropertyChanged target)
        {
            // 基于对象类型和当前状态分析最佳策略
            var typeName = target.GetType().Name;
            
            // 根据类型特征确定策略
            if (typeName.Contains("Collection") || typeName.Contains("List"))
            {
                return BatchingStrategy.Aggressive; // 集合类型，使用激进批处理
            }
            else if (typeName.Contains("ViewModel"))
            {
                return BatchingStrategy.Moderate; // ViewModel，使用适中批处理
            }
            
            return BatchingStrategy.Conservative; // 其他类型，使用保守批处理
        }

        /// <summary>
        /// 应用批处理策略
        /// </summary>
        private IBatchUpdateScope ApplyBatchingStrategy(INotifyPropertyChanged target, BatchingStrategy strategy)
        {
            switch (strategy)
            {
                case BatchingStrategy.Aggressive:
                    // 延长批处理时间，合并更多更新
                    var originalInterval = _batchUpdateInterval;
                    _batchUpdateInterval = TimeSpan.FromMilliseconds(200);
                    var scope = BeginBatchUpdate(target);
                    _batchUpdateInterval = originalInterval;
                    return scope;
                    
                case BatchingStrategy.Moderate:
                    return BeginBatchUpdate(target);
                    
                case BatchingStrategy.Conservative:
                default:
                    // 使用较短的批处理时间
                    var conservativeInterval = _batchUpdateInterval;
                    _batchUpdateInterval = TimeSpan.FromMilliseconds(25);
                    var conservativeScope = BeginBatchUpdate(target);
                    _batchUpdateInterval = conservativeInterval;
                    return conservativeScope;
            }
        }

        /// <summary>
        /// 批处理策略枚举
        /// </summary>
        private enum BatchingStrategy
        {
            Conservative,  // 保守批处理
            Moderate,      // 适中批处理  
            Aggressive     // 激进批处理
        }

        /// <summary>
        /// 在批量更新期间记录属性变更
        /// </summary>
        /// <param name="target">目标对象</param>
        /// <param name="propertyName">属性名称</param>
        public void RecordPropertyChange(INotifyPropertyChanged target, string propertyName)
        {
            if (_isDisposed || target == null || string.IsNullOrEmpty(propertyName))
                return;

            lock (_batchUpdateLock)
            {
                if (_batchUpdates.TryGetValue(target, out var context))
                {
                    context.PropertyChanges.Add(propertyName);
                }
            }
        }

        /// <summary>
        /// 结束批量更新并触发属性变更通知
        /// </summary>
        internal void EndBatchUpdate(INotifyPropertyChanged target, bool isRoot)
        {
            if (_isDisposed || target == null)
                return;

            BatchUpdateContext context;
            HashSet<string> propertiesToNotify = null;

            lock (_batchUpdateLock)
            {
                if (!_batchUpdates.TryGetValue(target, out context))
                    return;

                context.ReferenceCount--;

                if (context.ReferenceCount <= 0)
                {
                    // 最后一个引用，执行批量通知
                    _batchUpdates.Remove(target);
                    propertiesToNotify = new HashSet<string>(context.PropertyChanges);
                }
            }

            // 在锁外执行通知
            if (propertiesToNotify != null && propertiesToNotify.Count > 0)
            {
                ExecuteBatchNotification(target, propertiesToNotify, context);
            }
        }

        /// <summary>
        /// 执行批量属性变更通知
        /// </summary>
        private void ExecuteBatchNotification(INotifyPropertyChanged target, HashSet<string> properties, BatchUpdateContext context)
        {
            try
            {
                var duration = DateTime.UtcNow - context.StartTime;

                // 如果目标实现了批量更新接口，使用其批量方法
                if (target is ViewModelBase viewModelBase)
                {
                    viewModelBase.OnPropertiesChanged(properties.ToArray());
                }
                else
                {
                    // 否则逐个触发属性变更通知
                    foreach (var propertyName in properties)
                    {
                        // 使用反射或其他方式触发PropertyChanged事件
                        // 这里需要根据具体的INotifyPropertyChanged实现来调用
                        TriggerPropertyChanged(target, propertyName);
                    }
                }

                LogManager.Debug($"执行批量更新: {properties.Count}个属性, 耗时: {duration.TotalMilliseconds:F2}ms");
            }
            catch (Exception ex)
            {
                LogManager.Error($"执行批量更新失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 触发单个属性变更通知
        /// </summary>
        private void TriggerPropertyChanged(INotifyPropertyChanged target, string propertyName)
        {
            try
            {
                // 优先使用IPropertyChangeNotifier接口（安全方式，避免反射）
                if (target is IPropertyChangeNotifier notifier)
                {
                    notifier.NotifyPropertyChanged(propertyName);
                }
                else
                {
                    // 如果目标对象不实现IPropertyChangeNotifier接口，记录警告
                    // 我们无法安全地触发PropertyChanged事件，因为事件只能从内部触发
                    LogManager.Warning($"目标对象 ({target.GetType().Name}) 未实现IPropertyChangeNotifier接口，无法触发属性变更通知: {propertyName}");
                    LogManager.Info("建议更新ViewModel以实现IPropertyChangeNotifier接口，以支持智能数据绑定优化功能");
                    
                    // 不使用反射，而是直接跳过这个属性的变更通知
                    // 这是更安全的做法，避免潜在的线程安全问题
                }
            }
            catch (Exception ex)
            {
                LogManager.Warning($"触发属性变更通知失败 {propertyName}: {ex.Message}");
            }
        }

        #endregion

        #region 条件更新机制

        /// <summary>
        /// 配置条件更新 - 只有满足特定条件时才触发属性更新
        /// </summary>
        /// <param name="target">目标对象</param>
        /// <param name="propertyName">属性名称</param>
        /// <param name="condition">更新条件</param>
        /// <param name="config">条件配置</param>
        public void ConfigureConditionalUpdate(INotifyPropertyChanged target, string propertyName, 
            Func<object, object, bool> condition, ConditionalUpdateConfig config = null)
        {
            if (_isDisposed || target == null || string.IsNullOrEmpty(propertyName) || condition == null)
                return;

            var key = $"{target.GetHashCode()}_{propertyName}";
            config = config ?? ConditionalUpdateConfig.Default;

            lock (_conditionalConfigLock)
            {
                _conditionalConfigs[key] = new ConditionalUpdateConfig
                {
                    Condition = condition,
                    MinUpdateInterval = config.MinUpdateInterval,
                    MaxUpdateDelay = config.MaxUpdateDelay,
                    ThrottleMode = config.ThrottleMode,
                    LastUpdateTime = DateTime.MinValue,
                    PendingValue = null,
                    HasPendingUpdate = false
                };
            }
        }

        /// <summary>
        /// 检查是否应该执行条件更新
        /// </summary>
        /// <param name="target">目标对象</param>
        /// <param name="propertyName">属性名称</param>
        /// <param name="oldValue">旧值</param>
        /// <param name="newValue">新值</param>
        /// <returns>是否应该更新</returns>
        public bool ShouldUpdateProperty(INotifyPropertyChanged target, string propertyName, object oldValue, object newValue)
        {
            if (_isDisposed || target == null || string.IsNullOrEmpty(propertyName))
                return true;

            var key = $"{target.GetHashCode()}_{propertyName}";

            lock (_conditionalConfigLock)
            {
                if (!_conditionalConfigs.TryGetValue(key, out var config))
                    return true; // 没有配置条件，允许更新

                var now = DateTime.UtcNow;

                // 检查最小更新间隔
                if (now - config.LastUpdateTime < config.MinUpdateInterval)
                {
                    // 根据节流模式处理
                    switch (config.ThrottleMode)
                    {
                        case ThrottleMode.Skip:
                            return false;

                        case ThrottleMode.Delay:
                            config.PendingValue = newValue;
                            config.HasPendingUpdate = true;
                            
                            // 安排延迟更新
                            ScheduleConditionalUpdate(target, propertyName, config);
                            return false;

                        case ThrottleMode.Debounce:
                            // 重置等待时间
                            config.PendingValue = newValue;
                            config.HasPendingUpdate = true;
                            
                            ScheduleConditionalUpdate(target, propertyName, config);
                            return false;
                    }
                }

                // 检查条件
                if (!config.Condition(oldValue, newValue))
                {
                    return false;
                }

                // 更新最后更新时间
                config.LastUpdateTime = now;
                config.HasPendingUpdate = false;
                return true;
            }
        }

        /// <summary>
        /// 安排条件更新
        /// </summary>
        private void ScheduleConditionalUpdate(INotifyPropertyChanged target, string propertyName, ConditionalUpdateConfig config)
        {
            var delay = config.ThrottleMode == ThrottleMode.Debounce 
                ? config.MinUpdateInterval 
                : config.MaxUpdateDelay;

            Task.Delay(delay).ContinueWith(_ =>
            {
                if (_isDisposed || !config.HasPendingUpdate)
                    return;

                try
                {
                    // 执行延迟的更新
                    TriggerPropertyChanged(target, propertyName);

                    lock (_conditionalConfigLock)
                    {
                        config.LastUpdateTime = DateTime.UtcNow;
                        config.HasPendingUpdate = false;
                    }
                }
                catch (Exception ex)
                {
                    LogManager.Error($"执行条件更新失败 {propertyName}: {ex.Message}");
                }
            }, TaskScheduler.FromCurrentSynchronizationContext());
        }

        #endregion

        #region 统计和报告

        /// <summary>
        /// 获取优化器统计信息
        /// </summary>
        /// <returns>统计信息</returns>
        public OptimizerStatistics GetStatistics()
        {
            lock (_delayedUpdateLock)
            {
                lock (_batchUpdateLock)
                {
                    lock (_conditionalConfigLock)
                    {
                        return new OptimizerStatistics
                        {
                            ActiveDelayedUpdates = _delayedUpdates.Count,
                            ActiveBatchUpdates = _batchUpdates.Count,
                            ConfiguredConditionalUpdates = _conditionalConfigs.Count,
                            DefaultDelayInterval = _defaultDelayInterval,
                            BatchUpdateInterval = _batchUpdateInterval,
                            MaxBatchSize = _maxBatchSize
                        };
                    }
                }
            }
        }

        /// <summary>
        /// 生成优化报告
        /// </summary>
        /// <returns>优化报告</returns>
        public string GenerateOptimizationReport()
        {
            var stats = GetStatistics();
            var report = new System.Text.StringBuilder();

            report.AppendLine("=== 数据绑定优化报告 ===");
            report.AppendLine($"报告时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
            report.AppendLine();

            report.AppendLine("延迟更新机制:");
            report.AppendLine($"  活跃延迟更新: {stats.ActiveDelayedUpdates}");
            report.AppendLine($"  默认延迟间隔: {stats.DefaultDelayInterval.TotalMilliseconds}ms");
            report.AppendLine();

            report.AppendLine("批量更新机制:");
            report.AppendLine($"  活跃批量更新: {stats.ActiveBatchUpdates}");
            report.AppendLine($"  批量更新间隔: {stats.BatchUpdateInterval.TotalMilliseconds}ms");
            report.AppendLine($"  最大批量大小: {stats.MaxBatchSize}");
            report.AppendLine();

            report.AppendLine("条件更新机制:");
            report.AppendLine($"  配置的条件更新: {stats.ConfiguredConditionalUpdates}");

            return report.ToString();
        }

        #endregion

        #region IDisposable实现

        public void Dispose()
        {
            if (_isDisposed)
                return;

            _isDisposed = true;

            _delayedUpdateTimer?.Dispose();

            lock (_delayedUpdateLock)
            {
                _delayedUpdates.Clear();
            }

            lock (_batchUpdateLock)
            {
                _batchUpdates.Clear();
            }

            lock (_conditionalConfigLock)
            {
                _conditionalConfigs.Clear();
            }

            LogManager.Info("智能数据绑定优化器已释放");
        }

        #endregion
    }

    #region 辅助类和枚举

    /// <summary>
    /// 延迟更新上下文
    /// </summary>
    internal class DelayedUpdateContext
    {
        public string Key { get; set; }
        public WeakReference Target { get; set; }
        public string PropertyName { get; set; }
        public Action UpdateAction { get; set; }
        public DateTime ScheduledTime { get; set; }
        public int UpdateCount { get; set; }
    }

    /// <summary>
    /// 批量更新上下文
    /// </summary>
    internal class BatchUpdateContext
    {
        public INotifyPropertyChanged Target { get; set; }
        public DateTime StartTime { get; set; }
        public int ReferenceCount { get; set; }
        public HashSet<string> PropertyChanges { get; set; }
    }

    /// <summary>
    /// 节流模式
    /// </summary>
    public enum ThrottleMode
    {
        /// <summary>
        /// 跳过模式 - 在最小间隔内的更新直接跳过
        /// </summary>
        Skip,

        /// <summary>
        /// 延迟模式 - 延迟执行最后一次更新
        /// </summary>
        Delay,

        /// <summary>
        /// 防抖模式 - 连续更新时重置等待时间
        /// </summary>
        Debounce
    }

    /// <summary>
    /// 条件更新配置
    /// </summary>
    public class ConditionalUpdateConfig
    {
        public Func<object, object, bool> Condition { get; set; }
        public TimeSpan MinUpdateInterval { get; set; }
        public TimeSpan MaxUpdateDelay { get; set; }
        public ThrottleMode ThrottleMode { get; set; }

        // 内部状态
        internal DateTime LastUpdateTime { get; set; }
        internal object PendingValue { get; set; }
        internal bool HasPendingUpdate { get; set; }

        public static ConditionalUpdateConfig Default => new ConditionalUpdateConfig
        {
            Condition = (oldValue, newValue) => !Equals(oldValue, newValue),
            MinUpdateInterval = TimeSpan.FromMilliseconds(50),
            MaxUpdateDelay = TimeSpan.FromMilliseconds(500),
            ThrottleMode = ThrottleMode.Debounce
        };
    }

    /// <summary>
    /// 批量更新作用域接口
    /// </summary>
    public interface IBatchUpdateScope : IDisposable
    {
        void RecordPropertyChange(string propertyName);
    }

    /// <summary>
    /// 批量更新作用域实现
    /// </summary>
    internal class BatchUpdateScope : IBatchUpdateScope
    {
        private readonly SmartDataBindingOptimizer _optimizer;
        private readonly INotifyPropertyChanged _target;
        private readonly bool _isRoot;
        private bool _disposed = false;

        public BatchUpdateScope(SmartDataBindingOptimizer optimizer, INotifyPropertyChanged target, bool isRoot)
        {
            _optimizer = optimizer;
            _target = target;
            _isRoot = isRoot;
        }

        public void RecordPropertyChange(string propertyName)
        {
            if (!_disposed)
            {
                _optimizer.RecordPropertyChange(_target, propertyName);
            }
        }

        public void Dispose()
        {
            if (!_disposed)
            {
                _disposed = true;
                _optimizer.EndBatchUpdate(_target, _isRoot);
            }
        }
    }

    /// <summary>
    /// 空的批量更新作用域 - 用于禁用时的占位符
    /// </summary>
    internal class EmptyBatchScope : IBatchUpdateScope
    {
        public void RecordPropertyChange(string propertyName) { }
        public void Dispose() { }
    }

    /// <summary>
    /// 优化器统计信息
    /// </summary>
    public class OptimizerStatistics
    {
        public int ActiveDelayedUpdates { get; set; }
        public int ActiveBatchUpdates { get; set; }
        public int ConfiguredConditionalUpdates { get; set; }
        public TimeSpan DefaultDelayInterval { get; set; }
        public TimeSpan BatchUpdateInterval { get; set; }
        public int MaxBatchSize { get; set; }
    }

    #endregion
}