using System.ComponentModel;

namespace NavisworksTransport.Core.UIUpdate.Updates
{
    /// <summary>
    /// ViewModel属性刷新操作
    /// 专门用于触发ViewModel的PropertyChanged事件，刷新UI绑定
    /// </summary>
    public class ViewModelRefreshOperation : UIUpdateBase
    {
        #region 字段和属性

        /// <summary>
        /// 目标ViewModel
        /// </summary>
        public INotifyPropertyChanged ViewModel { get; }

        /// <summary>
        /// 要刷新的属性名称
        /// </summary>
        public string PropertyName { get; }

        #endregion

        #region 构造函数

        /// <summary>
        /// 初始化ViewModel刷新操作
        /// </summary>
        /// <param name="viewModel">目标ViewModel</param>
        /// <param name="propertyName">属性名称</param>
        /// <param name="priority">操作优先级</param>
        public ViewModelRefreshOperation(INotifyPropertyChanged viewModel, string propertyName, UIUpdatePriority priority = UIUpdatePriority.Normal)
            : base($"ViewModelRefresh_{propertyName}", $"刷新ViewModel属性{propertyName}", priority, UIFrameworkType.WPF)
        {
            ViewModel = viewModel ?? throw new ArgumentNullException(nameof(viewModel));
            PropertyName = propertyName ?? throw new ArgumentNullException(nameof(propertyName));
            SupportsRollback = false; // 属性刷新操作不支持回滚
        }

        #endregion

        #region 受保护方法重写

        /// <summary>
        /// 内部验证逻辑
        /// </summary>
        /// <param name="context">更新上下文</param>
        /// <returns>验证结果</returns>
        protected override UIUpdateValidationResult ValidateInternal(UIUpdateContext context)
        {
            if (ViewModel == null)
            {
                return UIUpdateValidationResult.Failure("ViewModel不能为空");
            }

            if (string.IsNullOrEmpty(PropertyName))
            {
                return UIUpdateValidationResult.Failure("属性名称不能为空");
            }

            // 检查ViewModel是否有对应的属性
            var propertyInfo = ViewModel.GetType().GetProperty(PropertyName);
            if (propertyInfo == null)
            {
                return UIUpdateValidationResult.Failure($"ViewModel不存在属性: {PropertyName}");
            }

            return UIUpdateValidationResult.Success();
        }

        /// <summary>
        /// 执行主要逻辑
        /// </summary>
        /// <param name="context">更新上下文</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>执行结果</returns>
        protected override async Task<UIUpdateResult> ExecuteInternalAsync(UIUpdateContext context, CancellationToken cancellationToken)
        {
            try
            {
                LogInfo($"刷新ViewModel属性: {PropertyName}");

                // 使用UIStateManager确保在UI线程上执行
                var uiStateManager = UIStateManager.Instance;
                
                await uiStateManager.ExecuteUIUpdateAsync(() =>
                {
                    // 优先使用IPropertyChangeNotifier接口（安全方式）
                    if (ViewModel is IPropertyChangeNotifier notifier)
                    {
                        notifier.NotifyPropertyChanged(PropertyName);
                    }
                    else
                    {
                        // 如果ViewModel不实现IPropertyChangeNotifier，直接触发PropertyChanged事件
                        // 这是最后的备用方案，避免使用反射
                        try
                        {
                            // 创建PropertyChangedEventArgs并尝试通过事件触发
                            var eventArgs = new PropertyChangedEventArgs(PropertyName);
                            
                            // 如果ViewModel有公共的PropertyChanged事件，我们可以通过显式访问来触发
                            // 但是由于事件的限制，我们无法从外部直接调用事件
                            // 这种情况下记录警告，提醒开发者ViewModel应该实现IPropertyChangeNotifier
                            LogManager.Warning($"ViewModel ({ViewModel.GetType().Name}) 未实现IPropertyChangeNotifier接口，无法安全触发属性变更通知");
                            throw new InvalidOperationException($"ViewModel必须实现IPropertyChangeNotifier接口才能使用ViewModelRefreshOperation");
                        }
                        catch (Exception ex)
                        {
                            LogManager.Error($"触发PropertyChanged事件失败: {ex.Message}");
                            throw new InvalidOperationException("无法找到触发PropertyChanged事件的方法，请确保ViewModel实现IPropertyChangeNotifier接口");
                        }
                    }
                }, context.TimeoutMilliseconds);

                LogInfo($"成功刷新ViewModel属性: {PropertyName}");
                return UIUpdateResult.Success($"成功刷新属性{PropertyName}", Id);
            }
            catch (Exception ex)
            {
                LogError($"刷新ViewModel属性{PropertyName}失败", ex);
                return UIUpdateResult.Failure($"刷新失败: {ex.Message}", ex, Id);
            }
        }

        #endregion
    }
}