using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Data;
using System.Windows.Threading;

namespace NavisworksTransport.UI.WPF.Services
{
    /// <summary>
    /// WPF绑定表达式优化器 - 减少不必要的绑定计算和UI刷新
    /// 通过缓存、批量处理和智能调度优化绑定性能
    /// </summary>
    public class BindingExpressionOptimizer : IDisposable
    {
        #region 字段和属性

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

        // 绑定表达式缓存
        private readonly ConcurrentDictionary<string, CachedBindingValue> _bindingCache;
        private readonly ConcurrentDictionary<BindingExpression, BindingMetadata> _bindingMetadata;

        // 优化配置
        private TimeSpan _cacheExpiration = TimeSpan.FromMinutes(5);
        private int _maxCacheSize = 1000;
        private bool _enableBindingCaching = true;
        private bool _enableBatchUpdate = true;
        private volatile bool _isDisposed = false;

        // 批量更新
        private readonly DispatcherTimer _batchUpdateTimer;
        private readonly HashSet<BindingExpression> _pendingUpdates;
        private readonly object _pendingUpdatesLock = new object();

        /// <summary>
        /// 获取绑定表达式优化器的单例实例
        /// </summary>
        public static BindingExpressionOptimizer Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (_instanceLock)
                    {
                        if (_instance == null)
                        {
                            _instance = new BindingExpressionOptimizer();
                        }
                    }
                }
                return _instance;
            }
        }

        /// <summary>
        /// 是否启用绑定缓存
        /// </summary>
        public bool EnableBindingCaching
        {
            get => _enableBindingCaching;
            set => _enableBindingCaching = value;
        }

        /// <summary>
        /// 是否启用批量更新
        /// </summary>
        public bool EnableBatchUpdate
        {
            get => _enableBatchUpdate;
            set => _enableBatchUpdate = value;
        }

        /// <summary>
        /// 缓存过期时间
        /// </summary>
        public TimeSpan CacheExpiration
        {
            get => _cacheExpiration;
            set => _cacheExpiration = value;
        }

        /// <summary>
        /// 最大缓存大小
        /// </summary>
        public int MaxCacheSize
        {
            get => _maxCacheSize;
            set => _maxCacheSize = Math.Max(10, value);
        }

        /// <summary>
        /// 当前缓存的绑定数量
        /// </summary>
        public int CachedBindingsCount => _bindingCache.Count;

        /// <summary>
        /// 等待批量更新的绑定数量
        /// </summary>
        public int PendingUpdatesCount
        {
            get
            {
                lock (_pendingUpdatesLock)
                {
                    return _pendingUpdates.Count;
                }
            }
        }

        #endregion

        #region 构造函数

        private BindingExpressionOptimizer()
        {
            _bindingCache = new ConcurrentDictionary<string, CachedBindingValue>();
            _bindingMetadata = new ConcurrentDictionary<BindingExpression, BindingMetadata>();
            _pendingUpdates = new HashSet<BindingExpression>();

            // 初始化批量更新定时器
            _batchUpdateTimer = new DispatcherTimer(DispatcherPriority.Background)
            {
                Interval = TimeSpan.FromMilliseconds(50)
            };
            _batchUpdateTimer.Tick += ProcessBatchUpdates;

            LogManager.Info("WPF绑定表达式优化器已初始化");
        }

        #endregion

        #region 绑定优化核心方法

        /// <summary>
        /// 优化绑定表达式 - 注册绑定以启用缓存和批量更新
        /// </summary>
        /// <param name="bindingExpression">绑定表达式</param>
        /// <param name="options">优化选项</param>
        public void OptimizeBinding(BindingExpression bindingExpression, BindingOptimizationOptions options = null)
        {
            if (_isDisposed || bindingExpression == null)
                return;

            options = options ?? BindingOptimizationOptions.Default;

            var metadata = new BindingMetadata
            {
                BindingExpression = bindingExpression,
                Options = options,
                RegistrationTime = DateTime.UtcNow,
                LastUpdateTime = DateTime.UtcNow,
                UpdateCount = 0
            };

            _bindingMetadata.TryAdd(bindingExpression, metadata);

            LogManager.Debug($"绑定表达式已注册优化: {GetBindingPath(bindingExpression)}");
        }

        /// <summary>
        /// 移除绑定优化 - 清理绑定相关的缓存和元数据
        /// </summary>
        /// <param name="bindingExpression">绑定表达式</param>
        public void RemoveBindingOptimization(BindingExpression bindingExpression)
        {
            if (_isDisposed || bindingExpression == null)
                return;

            _bindingMetadata.TryRemove(bindingExpression, out _);

            lock (_pendingUpdatesLock)
            {
                _pendingUpdates.Remove(bindingExpression);
            }

            // 清理相关缓存
            var bindingPath = GetBindingPath(bindingExpression);
            if (!string.IsNullOrEmpty(bindingPath))
            {
                _bindingCache.TryRemove(bindingPath, out _);
            }

            LogManager.Debug($"绑定表达式优化已移除: {bindingPath}");
        }

        /// <summary>
        /// 获取缓存的绑定值 - 如果缓存有效则返回缓存值，否则返回null
        /// </summary>
        /// <param name="bindingExpression">绑定表达式</param>
        /// <returns>缓存的值或null</returns>
        public object GetCachedValue(BindingExpression bindingExpression)
        {
            if (_isDisposed || !_enableBindingCaching || bindingExpression == null)
                return null;

            var bindingPath = GetBindingPath(bindingExpression);
            if (string.IsNullOrEmpty(bindingPath))
                return null;

            if (_bindingCache.TryGetValue(bindingPath, out var cachedValue))
            {
                if (DateTime.UtcNow - cachedValue.CacheTime < _cacheExpiration)
                {
                    cachedValue.AccessCount++;
                    cachedValue.LastAccessTime = DateTime.UtcNow;
                    return cachedValue.Value;
                }
                else
                {
                    // 缓存过期，移除
                    _bindingCache.TryRemove(bindingPath, out _);
                }
            }

            return null;
        }

        /// <summary>
        /// 缓存绑定值
        /// </summary>
        /// <param name="bindingExpression">绑定表达式</param>
        /// <param name="value">要缓存的值</param>
        public void CacheValue(BindingExpression bindingExpression, object value)
        {
            if (_isDisposed || !_enableBindingCaching || bindingExpression == null)
                return;

            var bindingPath = GetBindingPath(bindingExpression);
            if (string.IsNullOrEmpty(bindingPath))
                return;

            var cachedValue = new CachedBindingValue
            {
                Value = value,
                CacheTime = DateTime.UtcNow,
                LastAccessTime = DateTime.UtcNow,
                AccessCount = 1
            };

            _bindingCache.AddOrUpdate(bindingPath, cachedValue, (key, existing) => cachedValue);

            // 清理过期缓存
            if (_bindingCache.Count > _maxCacheSize)
            {
                CleanupExpiredCache();
            }
        }

        /// <summary>
        /// 调度批量绑定更新 - 将绑定更新加入批量处理队列
        /// </summary>
        /// <param name="bindingExpression">绑定表达式</param>
        public void ScheduleBatchUpdate(BindingExpression bindingExpression)
        {
            if (_isDisposed || !_enableBatchUpdate || bindingExpression == null)
            {
                // 如果不启用批量更新，立即更新
                UpdateBindingImmediately(bindingExpression);
                return;
            }

            lock (_pendingUpdatesLock)
            {
                _pendingUpdates.Add(bindingExpression);
            }

            // 启动批量更新定时器
            if (!_batchUpdateTimer.IsEnabled)
            {
                _batchUpdateTimer.Start();
            }
        }

        /// <summary>
        /// 立即更新绑定表达式
        /// </summary>
        /// <param name="bindingExpression">绑定表达式</param>
        private void UpdateBindingImmediately(BindingExpression bindingExpression)
        {
            if (_isDisposed || bindingExpression == null)
                return;

            try
            {
                bindingExpression.UpdateTarget();

                // 更新元数据
                if (_bindingMetadata.TryGetValue(bindingExpression, out var metadata))
                {
                    metadata.LastUpdateTime = DateTime.UtcNow;
                    metadata.UpdateCount++;
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"立即更新绑定失败: {ex.Message}");
            }
        }

        #endregion

        #region 批量更新处理

        /// <summary>
        /// 处理批量更新
        /// </summary>
        private void ProcessBatchUpdates(object sender, EventArgs e)
        {
            _batchUpdateTimer.Stop();

            List<BindingExpression> updatesToProcess;
            lock (_pendingUpdatesLock)
            {
                if (_pendingUpdates.Count == 0)
                    return;

                updatesToProcess = _pendingUpdates.ToList();
                _pendingUpdates.Clear();
            }

            if (updatesToProcess.Count == 0)
                return;

            try
            {
                // 按优先级和类型分组
                var groupedUpdates = GroupUpdatesByPriority(updatesToProcess);

                // 按优先级顺序处理
                foreach (var group in groupedUpdates.OrderByDescending(g => g.Key))
                {
                    ProcessUpdateGroup(group.Value);
                }

                LogManager.Debug($"批量更新完成: {updatesToProcess.Count}个绑定");
            }
            catch (Exception ex)
            {
                LogManager.Error($"批量更新处理失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 按优先级分组更新
        /// </summary>
        /// <param name="updates">更新列表</param>
        /// <returns>按优先级分组的更新</returns>
        private Dictionary<BindingUpdatePriority, List<BindingExpression>> GroupUpdatesByPriority(List<BindingExpression> updates)
        {
            var groups = new Dictionary<BindingUpdatePriority, List<BindingExpression>>();

            foreach (var update in updates)
            {
                var priority = BindingUpdatePriority.Normal;

                if (_bindingMetadata.TryGetValue(update, out var metadata))
                {
                    priority = metadata.Options.UpdatePriority;
                }

                if (!groups.TryGetValue(priority, out var group))
                {
                    group = new List<BindingExpression>();
                    groups[priority] = group;
                }

                group.Add(update);
            }

            return groups;
        }

        /// <summary>
        /// 处理单个更新组
        /// </summary>
        /// <param name="updates">更新组</param>
        private void ProcessUpdateGroup(List<BindingExpression> updates)
        {
            foreach (var update in updates)
            {
                try
                {
                    UpdateBindingImmediately(update);
                }
                catch (Exception ex)
                {
                    LogManager.Error($"处理绑定更新失败: {ex.Message}");
                }
            }
        }

        #endregion

        #region 缓存管理

        /// <summary>
        /// 清理过期缓存
        /// </summary>
        private void CleanupExpiredCache()
        {
            var cutoffTime = DateTime.UtcNow - _cacheExpiration;
            var expiredKeys = new List<string>();

            foreach (var kvp in _bindingCache)
            {
                if (kvp.Value.CacheTime < cutoffTime)
                {
                    expiredKeys.Add(kvp.Key);
                }
            }

            // 如果过期项目不足，按访问时间清理最久未访问的项目
            if (expiredKeys.Count < _bindingCache.Count - _maxCacheSize)
            {
                var lruKeys = _bindingCache
                    .Where(kvp => !expiredKeys.Contains(kvp.Key))
                    .OrderBy(kvp => kvp.Value.LastAccessTime)
                    .Take(_bindingCache.Count - _maxCacheSize)
                    .Select(kvp => kvp.Key)
                    .ToList();

                expiredKeys.AddRange(lruKeys);
            }

            // 移除选定的项目
            foreach (var key in expiredKeys)
            {
                _bindingCache.TryRemove(key, out _);
            }

            if (expiredKeys.Count > 0)
            {
                LogManager.Debug($"缓存清理完成: 移除{expiredKeys.Count}个项目");
            }
        }

        /// <summary>
        /// 清空所有缓存
        /// </summary>
        public void ClearCache()
        {
            _bindingCache.Clear();
            LogManager.Info("绑定缓存已清空");
        }

        /// <summary>
        /// 预热缓存 - 预加载常用绑定值
        /// </summary>
        /// <param name="bindingExpressions">要预热的绑定表达式</param>
        public void WarmupCache(IEnumerable<BindingExpression> bindingExpressions)
        {
            if (_isDisposed || !_enableBindingCaching || bindingExpressions == null)
                return;

            Task.Run(() =>
            {
                try
                {
                    foreach (var binding in bindingExpressions)
                    {
                        if (_isDisposed)
                            break;

                        try
                        {
                            // 触发绑定计算并缓存结果
                            var value = binding.Target?.GetValue(binding.TargetProperty);
                            if (value != null)
                            {
                                CacheValue(binding, value);
                            }
                        }
                        catch (Exception ex)
                        {
                            LogManager.Warning($"预热绑定缓存失败: {ex.Message}");
                        }
                    }

                    LogManager.Info("绑定缓存预热完成");
                }
                catch (Exception ex)
                {
                    LogManager.Error($"绑定缓存预热失败: {ex.Message}");
                }
            });
        }

        #endregion

        #region 辅助方法

        /// <summary>
        /// 获取绑定路径字符串
        /// </summary>
        /// <param name="bindingExpression">绑定表达式</param>
        /// <returns>绑定路径</returns>
        private string GetBindingPath(BindingExpression bindingExpression)
        {
            try
            {
                if (bindingExpression?.ParentBinding?.Path != null)
                {
                    var target = bindingExpression.Target;
                    var property = bindingExpression.TargetProperty;
                    var path = bindingExpression.ParentBinding.Path.Path;

                    return $"{target?.GetType().Name}.{property?.Name}:{path}";
                }
            }
            catch (Exception ex)
            {
                LogManager.Warning($"获取绑定路径失败: {ex.Message}");
            }

            return null;
        }

        /// <summary>
        /// 检查绑定是否应该被优化
        /// </summary>
        /// <param name="bindingExpression">绑定表达式</param>
        /// <returns>是否应该优化</returns>
        public bool ShouldOptimizeBinding(BindingExpression bindingExpression)
        {
            if (_isDisposed || bindingExpression == null)
                return false;

            // 检查绑定类型和复杂度
            var binding = bindingExpression.ParentBinding;
            if (binding == null)
                return false;

            // 简单的单向绑定更适合缓存
            if (binding.Mode == BindingMode.OneWay || binding.Mode == BindingMode.OneTime)
            {
                return true;
            }

            // 复杂的转换器绑定也适合缓存
            if (binding.Converter != null)
            {
                return true;
            }

            // 多级绑定路径适合优化
            var path = binding.Path?.Path;
            if (!string.IsNullOrEmpty(path) && path.Contains('.'))
            {
                return true;
            }

            return false;
        }

        #endregion

        #region 统计和报告

        /// <summary>
        /// 获取优化器统计信息
        /// </summary>
        /// <returns>统计信息</returns>
        public BindingOptimizerStatistics GetStatistics()
        {
            var totalAccess = _bindingCache.Values.Sum(v => v.AccessCount);
            var avgAccessPerBinding = _bindingCache.Count > 0 ? (double)totalAccess / _bindingCache.Count : 0;

            lock (_pendingUpdatesLock)
            {
                return new BindingOptimizerStatistics
                {
                    CachedBindingsCount = _bindingCache.Count,
                    RegisteredBindingsCount = _bindingMetadata.Count,
                    PendingUpdatesCount = _pendingUpdates.Count,
                    TotalCacheAccess = totalAccess,
                    AverageAccessPerBinding = avgAccessPerBinding,
                    CacheExpiration = _cacheExpiration,
                    MaxCacheSize = _maxCacheSize,
                    EnableBindingCaching = _enableBindingCaching,
                    EnableBatchUpdate = _enableBatchUpdate
                };
            }
        }

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

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

            report.AppendLine("缓存统计:");
            report.AppendLine($"  缓存绑定数: {stats.CachedBindingsCount}");
            report.AppendLine($"  注册绑定数: {stats.RegisteredBindingsCount}");
            report.AppendLine($"  总缓存访问: {stats.TotalCacheAccess:N0}");
            report.AppendLine($"  平均访问次数: {stats.AverageAccessPerBinding:F2}");
            report.AppendLine();

            report.AppendLine("批量更新统计:");
            report.AppendLine($"  等待更新数: {stats.PendingUpdatesCount}");
            report.AppendLine($"  批量更新: {(stats.EnableBatchUpdate ? "启用" : "禁用")}");
            report.AppendLine();

            report.AppendLine("配置信息:");
            report.AppendLine($"  绑定缓存: {(stats.EnableBindingCaching ? "启用" : "禁用")}");
            report.AppendLine($"  缓存过期时间: {stats.CacheExpiration.TotalMinutes:F1}分钟");
            report.AppendLine($"  最大缓存大小: {stats.MaxCacheSize}");
            report.AppendLine();

            // 性能建议
            var suggestions = GenerateOptimizationSuggestions(stats);
            if (suggestions.Count > 0)
            {
                report.AppendLine("优化建议:");
                foreach (var suggestion in suggestions)
                {
                    report.AppendLine($"  • {suggestion}");
                }
            }

            return report.ToString();
        }

        /// <summary>
        /// 生成优化建议
        /// </summary>
        /// <param name="stats">统计信息</param>
        /// <returns>建议列表</returns>
        private List<string> GenerateOptimizationSuggestions(BindingOptimizerStatistics stats)
        {
            var suggestions = new List<string>();

            if (stats.CachedBindingsCount == 0 && stats.RegisteredBindingsCount > 0)
            {
                suggestions.Add("建议启用绑定缓存以提高性能");
            }

            if (stats.AverageAccessPerBinding < 2)
            {
                suggestions.Add("缓存利用率较低，考虑调整缓存策略或减少缓存大小");
            }

            if (stats.PendingUpdatesCount > 50)
            {
                suggestions.Add("批量更新队列较长，考虑减少批量更新间隔");
            }

            if (stats.CachedBindingsCount > stats.MaxCacheSize * 0.9)
            {
                suggestions.Add("缓存接近容量上限，考虑增加最大缓存大小");
            }

            return suggestions;
        }

        #endregion

        #region IDisposable实现

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

            _isDisposed = true;

            _batchUpdateTimer?.Stop();
            if (_batchUpdateTimer != null)
            {
                _batchUpdateTimer.Tick -= ProcessBatchUpdates;
            }

            _bindingCache.Clear();
            _bindingMetadata.Clear();

            lock (_pendingUpdatesLock)
            {
                _pendingUpdates.Clear();
            }

            LogManager.Info("WPF绑定表达式优化器已释放");
        }

        #endregion
    }

    #region 辅助类和枚举

    /// <summary>
    /// 缓存的绑定值
    /// </summary>
    internal class CachedBindingValue
    {
        public object Value { get; set; }
        public DateTime CacheTime { get; set; }
        public DateTime LastAccessTime { get; set; }
        public int AccessCount { get; set; }
    }

    /// <summary>
    /// 绑定元数据
    /// </summary>
    internal class BindingMetadata
    {
        public BindingExpression BindingExpression { get; set; }
        public BindingOptimizationOptions Options { get; set; }
        public DateTime RegistrationTime { get; set; }
        public DateTime LastUpdateTime { get; set; }
        public int UpdateCount { get; set; }
    }

    /// <summary>
    /// 绑定优化选项
    /// </summary>
    public class BindingOptimizationOptions
    {
        /// <summary>
        /// 更新优先级
        /// </summary>
        public BindingUpdatePriority UpdatePriority { get; set; } = BindingUpdatePriority.Normal;

        /// <summary>
        /// 是否启用缓存
        /// </summary>
        public bool EnableCaching { get; set; } = true;

        /// <summary>
        /// 是否启用批量更新
        /// </summary>
        public bool EnableBatchUpdate { get; set; } = true;

        /// <summary>
        /// 缓存生存时间
        /// </summary>
        public TimeSpan? CacheTtl { get; set; }

        /// <summary>
        /// 默认优化选项
        /// </summary>
        public static BindingOptimizationOptions Default => new BindingOptimizationOptions();

        /// <summary>
        /// 高性能选项 - 启用所有优化
        /// </summary>
        public static BindingOptimizationOptions HighPerformance => new BindingOptimizationOptions
        {
            UpdatePriority = BindingUpdatePriority.Low,
            EnableCaching = true,
            EnableBatchUpdate = true,
            CacheTtl = TimeSpan.FromMinutes(10)
        };

        /// <summary>
        /// 实时选项 - 禁用批量更新，保持响应性
        /// </summary>
        public static BindingOptimizationOptions RealTime => new BindingOptimizationOptions
        {
            UpdatePriority = BindingUpdatePriority.High,
            EnableCaching = false,
            EnableBatchUpdate = false
        };
    }

    /// <summary>
    /// 绑定更新优先级
    /// </summary>
    public enum BindingUpdatePriority
    {
        /// <summary>
        /// 低优先级 - 可以延迟更新
        /// </summary>
        Low = 0,

        /// <summary>
        /// 普通优先级 - 正常更新
        /// </summary>
        Normal = 1,

        /// <summary>
        /// 高优先级 - 优先更新
        /// </summary>
        High = 2,

        /// <summary>
        /// 关键优先级 - 立即更新
        /// </summary>
        Critical = 3
    }

    /// <summary>
    /// 绑定优化器统计信息
    /// </summary>
    public class BindingOptimizerStatistics
    {
        public int CachedBindingsCount { get; set; }
        public int RegisteredBindingsCount { get; set; }
        public int PendingUpdatesCount { get; set; }
        public long TotalCacheAccess { get; set; }
        public double AverageAccessPerBinding { get; set; }
        public TimeSpan CacheExpiration { get; set; }
        public int MaxCacheSize { get; set; }
        public bool EnableBindingCaching { get; set; }
        public bool EnableBatchUpdate { get; set; }
    }

    #endregion
}