using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NavisworksTransport.Core;
using NavisworksTransport.UI.WPF.Services;
using NavisworksTransport.UI.WPF.Interfaces;

namespace NavisworksTransport.UI.WPF.ViewModels
{
    /// <summary>
    /// ViewModel基类，实现INotifyPropertyChanged接口
    /// 集成UIStateManager提供线程安全的属性更新和防重入机制
    /// 集成智能数据绑定优化功能，支持延迟更新、批量更新和条件更新
    /// </summary>
    public abstract class ViewModelBase : IPropertyChangeNotifier
    {
        #region 字段和属性

        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// UI状态管理器，提供线程安全的UI更新机制
        /// </summary>
        private readonly UIStateManager _uiStateManager;

        /// <summary>
        /// 智能数据绑定优化器，提供延迟更新、批量更新等优化功能
        /// </summary>
        private readonly SmartDataBindingOptimizer _bindingOptimizer;

        /// <summary>
        /// 正在更新的属性集合，用于防重入检测
        /// </summary>
        private readonly HashSet<string> _updatingProperties = new HashSet<string>();

        /// <summary>
        /// 属性更新锁，确保线程安全
        /// </summary>
        private readonly object _propertyLock = new object();

        /// <summary>
        /// 是否启用智能优化功能
        /// </summary>
        protected bool IsSmartOptimizationEnabled { get; set; } = true;

        /// <summary>
        /// 主ViewModel引用，用于统一状态栏更新
        /// </summary>
        protected LogisticsControlViewModel _mainViewModel;

        #endregion

        #region 构造函数

        /// <summary>
        /// 初始化ViewModelBase
        /// </summary>
        protected ViewModelBase()
        {
            _uiStateManager = UIStateManager.Instance;
            _bindingOptimizer = SmartDataBindingOptimizer.Instance;
        }

        #endregion

        #region 属性更新方法

        /// <summary>
        /// 触发属性变更通知（线程安全，防重入）
        /// </summary>
        /// <param name="propertyName">属性名称，自动获取调用者名称</param>
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            if (string.IsNullOrEmpty(propertyName))
            {
                return;
            }

            try
            {
                // 防重入检查
                lock (_propertyLock)
                {
                    if (_updatingProperties.Contains(propertyName))
                    {
                        // 属性正在更新中，防止重入
                        LogManager.Debug($"[ViewModel] 检测到属性重入更新，跳过: {propertyName}");
                        return;
                    }

                    // 标记属性为正在更新状态
                    _updatingProperties.Add(propertyName);
                }

                // 使用UIStateManager确保在UI线程上安全执行
                if (_uiStateManager.IsUIThread)
                {
                    // 已在UI线程上，直接触发
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
                }
                else
                {
                    // 异步切换到UI线程执行
                    _ = _uiStateManager.ExecuteUIUpdateAsync(() =>
                    {
                        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
                    });
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"[ViewModel] OnPropertyChanged失败: {ex.Message}，属性: {propertyName}");
            }
            finally
            {
                // 清除更新标记
                lock (_propertyLock)
                {
                    _updatingProperties.Remove(propertyName);
                }
            }
        }

        /// <summary>
        /// 公共接口：触发指定属性的变更通知（供外部组件使用，替代反射调用）
        /// </summary>
        /// <param name="propertyName">属性名称</param>
        public virtual void NotifyPropertyChanged(string propertyName)
        {
            OnPropertyChanged(propertyName);
        }

        /// <summary>
        /// 同步触发属性变更通知（确保在UI线程上执行完成）
        /// </summary>
        /// <param name="propertyName">属性名称</param>
        /// <param name="timeout">超时时间（毫秒），默认3000ms</param>
        protected virtual async Task OnPropertyChangedAsync(string propertyName, int timeout = 3000)
        {
            if (string.IsNullOrEmpty(propertyName))
            {
                return;
            }

            // 防重入检查
            lock (_propertyLock)
            {
                if (_updatingProperties.Contains(propertyName))
                {
                    LogManager.Debug($"[ViewModel] 检测到属性重入更新，跳过: {propertyName}");
                    return;
                }
                
                _updatingProperties.Add(propertyName);
            }

            try
            {
                // 使用UIStateManager确保同步执行
                await _uiStateManager.ExecuteUIUpdateAsync(() =>
                {
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
                }, timeout);
            }
            catch (Exception ex)
            {
                LogManager.Error($"[ViewModel] OnPropertyChangedAsync失败: {ex.Message}，属性: {propertyName}");
                throw;
            }
            finally
            {
                lock (_propertyLock)
                {
                    _updatingProperties.Remove(propertyName);
                }
            }
        }

        /// <summary>
        /// 批量触发属性变更通知（原子性操作）
        /// </summary>
        /// <param name="propertyNames">要更新的属性名称数组</param>
        public virtual void OnPropertiesChanged(params string[] propertyNames)
        {
            if (propertyNames == null || propertyNames.Length == 0)
            {
                return;
            }

            // 去重并过滤空值
            var uniqueProperties = propertyNames.Where(p => !string.IsNullOrEmpty(p)).Distinct().ToArray();
            if (uniqueProperties.Length == 0)
            {
                return;
            }

            // 防重入检查
            var propertiesToUpdate = new List<string>();
            lock (_propertyLock)
            {
                foreach (var propertyName in uniqueProperties)
                {
                    if (!_updatingProperties.Contains(propertyName))
                    {
                        _updatingProperties.Add(propertyName);
                        propertiesToUpdate.Add(propertyName);
                    }
                    else
                    {
                        LogManager.Debug($"[ViewModel] 检测到属性重入更新，跳过: {propertyName}");
                    }
                }
            }

            if (propertiesToUpdate.Count == 0)
            {
                return; // 所有属性都在更新中，避免重入
            }

            try
            {
                // 创建批量更新操作
                var updateActions = propertiesToUpdate.Select(propertyName =>
                    new Action(() => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)))
                ).ToArray();

                // 使用UIStateManager批量执行
                _ = _uiStateManager.ExecuteBatchUIUpdate(updateActions);
            }
            catch (Exception ex)
            {
                LogManager.Error($"[ViewModel] OnPropertiesChanged失败: {ex.Message}，属性: {string.Join(", ", propertiesToUpdate)}");
            }
            finally
            {
                // 清除所有更新标记
                lock (_propertyLock)
                {
                    foreach (var propertyName in propertiesToUpdate)
                    {
                        _updatingProperties.Remove(propertyName);
                    }
                }
            }
        }

        /// <summary>
        /// 批量设置属性值并触发变更通知（原子性操作）
        /// </summary>
        /// <param name="properties">属性名称和值的键值对数组</param>
        protected virtual void SetProperties(params (string name, object value)[] properties)
        {
            if (properties == null || properties.Length == 0)
            {
                return;
            }

            try
            {
                // 批量更新操作
                var updateActions = properties.Select(p =>
                    new Action(() => OnPropertyChanged(p.name))
                ).ToArray();

                // 使用UIStateManager批量执行
                _ = _uiStateManager.ExecuteBatchUIUpdate(updateActions);
            }
            catch (Exception ex)
            {
                LogManager.Error($"[ViewModel] SetProperties失败: {ex.Message}");
            }
        }

        #endregion

        #region 属性设置方法

        /// <summary>
        /// 设置属性值并触发变更通知（线程安全）
        /// </summary>
        /// <typeparam name="T">属性类型</typeparam>
        /// <param name="field">字段引用</param>
        /// <param name="value">新值</param>
        /// <param name="propertyName">属性名称，自动获取调用者名称</param>
        /// <returns>如果值发生变化返回true</returns>
        protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
        {
            if (EqualityComparer<T>.Default.Equals(field, value)) 
                return false;
            
            field = value;
            OnPropertyChanged(propertyName);
            return true;
        }

        /// <summary>
        /// 异步设置属性值并触发变更通知（确保UI线程同步执行）
        /// </summary>
        /// <typeparam name="T">属性类型</typeparam>
        /// <param name="field">字段引用</param>
        /// <param name="value">新值</param>
        /// <param name="propertyName">属性名称，自动获取调用者名称</param>
        /// <param name="timeout">超时时间（毫秒），默认3000ms</param>
        /// <returns>如果值发生变化返回true</returns>
        protected async Task<bool> SetPropertyAsync<T>(T field, T value, [CallerMemberName] string propertyName = null, int timeout = 3000)
        {
            if (EqualityComparer<T>.Default.Equals(field, value)) 
                return false;
            
            await OnPropertyChangedAsync(propertyName, timeout);
            return true;
        }

        /// <summary>
        /// 线程安全的属性设置方法（使用UIStateManager确保线程安全）
        /// </summary>
        /// <typeparam name="T">属性类型</typeparam>
        /// <param name="field">字段引用</param>
        /// <param name="value">新值</param>
        /// <param name="propertyName">属性名称，自动获取调用者名称</param>
        /// <returns>如果值发生变化返回true</returns>
        protected bool SetPropertyThreadSafe<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
        {
            if (EqualityComparer<T>.Default.Equals(field, value)) 
                return false;
            
            field = value;
            
            // 使用UIStateManager确保在UI线程上触发属性变更通知
            if (_uiStateManager.IsUIThread)
            {
                OnPropertyChanged(propertyName);
            }
            else
            {
                _ = _uiStateManager.ExecuteUIUpdateAsync(() => OnPropertyChanged(propertyName));
            }
            
            return true;
        }

        #endregion

        #region 智能数据绑定优化方法

        /// <summary>
        /// 延迟触发属性变更通知 - 将快速连续的更新合并为一次通知
        /// </summary>
        /// <param name="propertyName">属性名称</param>
        /// <param name="delayInterval">延迟间隔，null使用默认值</param>
        protected void OnPropertyChangedDelayed([CallerMemberName] string propertyName = null, TimeSpan? delayInterval = null)
        {
            if (!IsSmartOptimizationEnabled || string.IsNullOrEmpty(propertyName))
            {
                OnPropertyChanged(propertyName);
                return;
            }

            _bindingOptimizer.RegisterDelayedUpdate(this, propertyName, () => OnPropertyChanged(propertyName), delayInterval);
        }

        /// <summary>
        /// 条件性触发属性变更通知 - 只有满足条件时才触发更新
        /// </summary>
        /// <typeparam name="T">属性类型</typeparam>
        /// <param name="field">字段引用</param>
        /// <param name="value">新值</param>
        /// <param name="condition">更新条件</param>
        /// <param name="propertyName">属性名称</param>
        /// <returns>是否触发了更新</returns>
        protected bool SetPropertyConditional<T>(ref T field, T value, Func<T, T, bool> condition, [CallerMemberName] string propertyName = null)
        {
            if (condition != null && !condition(field, value))
                return false;

            return SetProperty(ref field, value, propertyName);
        }

        /// <summary>
        /// 设置属性值并支持智能优化
        /// </summary>
        /// <typeparam name="T">属性类型</typeparam>
        /// <param name="field">字段引用</param>
        /// <param name="value">新值</param>
        /// <param name="updateMode">更新模式</param>
        /// <param name="propertyName">属性名称</param>
        /// <returns>是否发生了变化</returns>
        public bool SetPropertySmart<T>(ref T field, T value, PropertyUpdateMode updateMode = PropertyUpdateMode.Immediate, [CallerMemberName] string propertyName = null)
        {
            if (EqualityComparer<T>.Default.Equals(field, value))
                return false;

            var oldValue = field;
            field = value;

            switch (updateMode)
            {
                case PropertyUpdateMode.Immediate:
                    OnPropertyChanged(propertyName);
                    break;

                case PropertyUpdateMode.Delayed:
                    OnPropertyChangedDelayed(propertyName);
                    break;

                case PropertyUpdateMode.Conditional:
                    if (IsSmartOptimizationEnabled)
                    {
                        if (_bindingOptimizer.ShouldUpdateProperty(this, propertyName, oldValue, value))
                        {
                            OnPropertyChanged(propertyName);
                        }
                    }
                    else
                    {
                        OnPropertyChanged(propertyName);
                    }
                    break;
            }

            return true;
        }

        /// <summary>
        /// 开始批量属性更新 - 在作用域内的所有属性更新将被合并
        /// </summary>
        /// <returns>批量更新作用域</returns>
        public IBatchUpdateScope BeginBatchUpdate()
        {
            if (!IsSmartOptimizationEnabled)
                return new EmptyBatchScope();

            return _bindingOptimizer.BeginBatchUpdate(this);
        }

        /// <summary>
        /// 配置属性的条件更新规则
        /// </summary>
        /// <param name="propertyName">属性名称</param>
        /// <param name="condition">更新条件</param>
        /// <param name="config">条件配置</param>
        public void ConfigurePropertyUpdate(string propertyName, Func<object, object, bool> condition, ConditionalUpdateConfig config = null)
        {
            if (!IsSmartOptimizationEnabled || string.IsNullOrEmpty(propertyName))
                return;

            _bindingOptimizer.ConfigureConditionalUpdate(this, propertyName, condition, config);
        }

        /// <summary>
        /// 立即刷新所有延迟的属性更新
        /// </summary>
        protected void FlushDelayedUpdates()
        {
            if (IsSmartOptimizationEnabled)
            {
                _bindingOptimizer.FlushDelayedUpdates(this);
            }
        }

        /// <summary>
        /// 批量设置多个属性（在单个批量更新作用域内）
        /// </summary>
        /// <param name="propertyUpdates">属性更新操作集合</param>
        protected void SetPropertiesBatch(params Action[] propertyUpdates)
        {
            if (propertyUpdates == null || propertyUpdates.Length == 0)
                return;

            using (BeginBatchUpdate())
            {
                foreach (var update in propertyUpdates)
                {
                    try
                    {
                        update?.Invoke();
                    }
                    catch (Exception ex)
                    {
                        LogManager.Error($"[ViewModel] 批量属性更新失败: {ex.Message}");
                    }
                }
            }
        }

        #endregion

        #region 诊断方法

        /// <summary>
        /// 启用或禁用智能优化
        /// </summary>
        /// <param name="enabled">是否启用</param>
        protected void SetSmartOptimization(bool enabled)
        {
            IsSmartOptimizationEnabled = enabled;
        }

        /// <summary>
        /// 获取智能优化器的统计信息
        /// </summary>
        /// <returns>优化器统计</returns>
        protected OptimizerStatistics GetOptimizerStatistics()
        {
            return _bindingOptimizer.GetStatistics();
        }

        #endregion

        #region 安全执行方法

        /// <summary>
        /// 安全执行操作，捕获异常（使用UIStateManager确保线程安全）
        /// </summary>
        /// <param name="action">要执行的操作</param>
        /// <param name="operationName">操作名称</param>
        /// <param name="runOnUIThread">是否强制在UI线程上执行</param>
        protected void SafeExecute(Action action, string operationName = "操作", bool runOnUIThread = false)
        {
            if (action == null)
            {
                LogManager.Warning($"[ViewModel] SafeExecute接收到空操作: {operationName}");
                return;
            }

            try
            {
                if (runOnUIThread && !_uiStateManager.IsUIThread)
                {
                    // 异步切换到UI线程执行
                    _ = _uiStateManager.ExecuteUIUpdateAsync(action);
                }
                else
                {
                    // 直接执行
                    action();
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"[ViewModel] {operationName}失败: {ex.Message}");
                LogManager.Error($"[ViewModel] 堆栈信息: {ex.StackTrace}");
            }
        }

        /// <summary>
        /// 安全执行操作，捕获异常并返回结果（使用UIStateManager确保线程安全）
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="func">要执行的函数</param>
        /// <param name="defaultValue">默认返回值</param>
        /// <param name="operationName">操作名称</param>
        /// <param name="runOnUIThread">是否强制在UI线程上执行</param>
        /// <returns>执行结果或默认值</returns>
        protected T SafeExecute<T>(Func<T> func, T defaultValue = default(T), string operationName = "操作", bool runOnUIThread = false)
        {
            if (func == null)
            {
                LogManager.Warning($"[ViewModel] SafeExecute接收到空函数: {operationName}");
                return defaultValue;
            }

            try
            {
                if (runOnUIThread && !_uiStateManager.IsUIThread)
                {
                    // 同步切换到UI线程执行
                    return _uiStateManager.ExecuteUIUpdateAsync(func).Result;
                }
                else
                {
                    // 直接执行
                    return func();
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"[ViewModel] {operationName}失败: {ex.Message}");
                LogManager.Error($"[ViewModel] 堆栈信息: {ex.StackTrace}");
                return defaultValue;
            }
        }

        /// <summary>
        /// 异步安全执行操作，捕获异常（确保在UI线程上执行）
        /// </summary>
        /// <param name="action">要执行的操作</param>
        /// <param name="operationName">操作名称</param>
        /// <param name="timeout">超时时间（毫秒），默认5000ms</param>
        protected async Task SafeExecuteAsync(Action action, string operationName = "操作", int timeout = 5000)
        {
            if (action == null)
            {
                LogManager.Warning($"[ViewModel] SafeExecuteAsync接收到空操作: {operationName}");
                return;
            }

            try
            {
                await _uiStateManager.ExecuteUIUpdateAsync(action, timeout);
            }
            catch (Exception ex)
            {
                LogManager.Error($"[ViewModel] {operationName}异步执行失败: {ex.Message}");
                LogManager.Error($"[ViewModel] 堆栈信息: {ex.StackTrace}");
            }
        }

        /// <summary>
        /// 异步安全执行操作，捕获异常并返回结果（确保在UI线程上执行）
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="func">要执行的函数</param>
        /// <param name="defaultValue">默认返回值</param>
        /// <param name="operationName">操作名称</param>
        /// <param name="timeout">超时时间（毫秒），默认5000ms</param>
        /// <returns>执行结果或默认值</returns>
        protected async Task<T> SafeExecuteAsync<T>(Func<T> func, T defaultValue = default(T), string operationName = "操作", int timeout = 5000)
        {
            if (func == null)
            {
                LogManager.Warning($"[ViewModel] SafeExecuteAsync接收到空函数: {operationName}");
                return defaultValue;
            }

            try
            {
                return await _uiStateManager.ExecuteUIUpdateAsync(func, timeout);
            }
            catch (Exception ex)
            {
                LogManager.Error($"[ViewModel] {operationName}异步执行失败: {ex.Message}");
                LogManager.Error($"[ViewModel] 堆栈信息: {ex.StackTrace}");
                return defaultValue;
            }
        }

        #endregion

        #region 统一状态栏更新方法

        /// <summary>
        /// 设置主ViewModel引用
        /// </summary>
        /// <param name="mainViewModel">主ViewModel实例</param>
        protected void SetMainViewModel(LogisticsControlViewModel mainViewModel)
        {
            _mainViewModel = mainViewModel;
        }

        /// <summary>
        /// 更新统一状态栏（简单版本，不显示进度条）
        /// </summary>
        /// <param name="message">状态消息</param>
        protected void UpdateMainStatus(string message)
        {
            try
            {
                // 如果有主ViewModel引用，更新统一状态栏
                if (_mainViewModel != null)
                {
                    _mainViewModel.UpdateStatus(message);
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"更新统一状态栏失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 更新统一状态栏（支持百分比进度）
        /// </summary>
        /// <param name="message">状态消息</param>
        /// <param name="percentage">进度百分比</param>
        protected void UpdateMainStatus(string message, double percentage)
        {
            try
            {
                // 如果有主ViewModel引用，更新统一状态栏
                if (_mainViewModel != null)
                {
                    _mainViewModel.UpdateStatus(message, percentage);
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"更新统一状态栏失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 更新统一状态栏（完整版本，支持不确定进度）
        /// </summary>
        /// <param name="message">状态消息</param>
        /// <param name="progress">进度值（-1表示不确定进度）</param>
        /// <param name="isProcessing">是否正在处理（可选）</param>
        protected void UpdateMainStatus(string message, double progress = -1, bool? isProcessing = null)
        {
            try
            {
                // 如果有主ViewModel引用，更新统一状态栏
                if (_mainViewModel != null)
                {
                    _mainViewModel.UpdateStatus(message, progress, isProcessing);
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"更新统一状态栏失败: {ex.Message}", ex);
            }
        }

        #endregion
    }

    /// <summary>
    /// 属性更新模式枚举
    /// </summary>
    public enum PropertyUpdateMode
    {
        /// <summary>
        /// 立即更新 - 传统模式，立即触发属性变更通知
        /// </summary>
        Immediate,

        /// <summary>
        /// 延迟更新 - 将快速连续的更新合并，在指定延迟后统一触发
        /// </summary>
        Delayed,

        /// <summary>
        /// 条件更新 - 根据预配置的条件和频率限制决定是否触发更新
        /// </summary>
        Conditional
    }
}