using System.ComponentModel;

namespace NavisworksTransport.Core.UIUpdate
{
    /// <summary>
    /// UI更新操作工厂
    /// 提供便捷的UI更新操作创建方法，简化常见UI更新场景的使用
    /// </summary>
    public static class UIUpdateFactory
    {
        #region 属性更新工厂方法

        /// <summary>
        /// 创建属性更新操作
        /// </summary>
        /// <param name="target">目标对象</param>
        /// <param name="propertyName">属性名称</param>
        /// <param name="newValue">新值</param>
        /// <param name="priority">操作优先级</param>
        /// <returns>属性更新操作</returns>
        public static PropertyUpdateOperation UpdateProperty(object target, string propertyName, object newValue, UIUpdatePriority priority = UIUpdatePriority.Normal)
        {
            return new PropertyUpdateOperation(target, propertyName, newValue, priority);
        }

        /// <summary>
        /// 创建多个属性更新操作
        /// </summary>
        /// <param name="target">目标对象</param>
        /// <param name="properties">属性名称和值的键值对</param>
        /// <param name="priority">操作优先级</param>
        /// <returns>属性更新操作集合</returns>
        public static IEnumerable<PropertyUpdateOperation> UpdateProperties(object target, Dictionary<string, object> properties, UIUpdatePriority priority = UIUpdatePriority.Normal)
        {
            if (target == null || properties == null)
            {
                return Enumerable.Empty<PropertyUpdateOperation>();
            }

            return properties.Select(kvp => new PropertyUpdateOperation(target, kvp.Key, kvp.Value, priority));
        }

        /// <summary>
        /// 创建属性更新操作（使用匿名对象）
        /// </summary>
        /// <param name="target">目标对象</param>
        /// <param name="values">包含属性值的匿名对象</param>
        /// <param name="priority">操作优先级</param>
        /// <returns>属性更新操作集合</returns>
        public static IEnumerable<PropertyUpdateOperation> UpdateProperties(object target, object values, UIUpdatePriority priority = UIUpdatePriority.Normal)
        {
            if (target == null || values == null)
            {
                return Enumerable.Empty<PropertyUpdateOperation>();
            }

            var properties = TypeDescriptor.GetProperties(values);
            var operations = new List<PropertyUpdateOperation>();

            foreach (PropertyDescriptor property in properties)
            {
                var value = property.GetValue(values);
                operations.Add(new PropertyUpdateOperation(target, property.Name, value, priority));
            }

            return operations;
        }

        #endregion

        #region 集合更新工厂方法

        /// <summary>
        /// 创建集合添加操作
        /// </summary>
        /// <param name="collection">目标集合</param>
        /// <param name="item">要添加的项目</param>
        /// <param name="priority">操作优先级</param>
        /// <returns>集合更新操作</returns>
        public static CollectionUpdateOperation AddToCollection(object collection, object item, UIUpdatePriority priority = UIUpdatePriority.Normal)
        {
            return new CollectionUpdateOperation(collection, CollectionUpdateType.Add, item, priority: priority);
        }

        /// <summary>
        /// 创建集合删除操作
        /// </summary>
        /// <param name="collection">目标集合</param>
        /// <param name="item">要删除的项目</param>
        /// <param name="priority">操作优先级</param>
        /// <returns>集合更新操作</returns>
        public static CollectionUpdateOperation RemoveFromCollection(object collection, object item, UIUpdatePriority priority = UIUpdatePriority.Normal)
        {
            return new CollectionUpdateOperation(collection, CollectionUpdateType.Remove, item, priority: priority);
        }

        /// <summary>
        /// 创建集合清空操作
        /// </summary>
        /// <param name="collection">目标集合</param>
        /// <param name="priority">操作优先级</param>
        /// <returns>集合更新操作</returns>
        public static CollectionUpdateOperation ClearCollection(object collection, UIUpdatePriority priority = UIUpdatePriority.Normal)
        {
            return new CollectionUpdateOperation(collection, CollectionUpdateType.Clear, priority: priority);
        }

        /// <summary>
        /// 创建集合插入操作
        /// </summary>
        /// <param name="collection">目标集合</param>
        /// <param name="index">插入位置</param>
        /// <param name="item">要插入的项目</param>
        /// <param name="priority">操作优先级</param>
        /// <returns>集合更新操作</returns>
        public static CollectionUpdateOperation InsertIntoCollection(object collection, int index, object item, UIUpdatePriority priority = UIUpdatePriority.Normal)
        {
            return new CollectionUpdateOperation(collection, CollectionUpdateType.Insert, item, index, priority);
        }

        /// <summary>
        /// 创建集合替换操作
        /// </summary>
        /// <param name="collection">目标集合</param>
        /// <param name="index">替换位置</param>
        /// <param name="item">新项目</param>
        /// <param name="priority">操作优先级</param>
        /// <returns>集合更新操作</returns>
        public static CollectionUpdateOperation ReplaceInCollection(object collection, int index, object item, UIUpdatePriority priority = UIUpdatePriority.Normal)
        {
            return new CollectionUpdateOperation(collection, CollectionUpdateType.Replace, item, index, priority);
        }

        /// <summary>
        /// 创建集合批量添加操作
        /// </summary>
        /// <param name="collection">目标集合</param>
        /// <param name="items">要添加的项目集合</param>
        /// <param name="priority">操作优先级</param>
        /// <returns>集合更新操作</returns>
        public static CollectionUpdateOperation AddRangeToCollection(object collection, IEnumerable<object> items, UIUpdatePriority priority = UIUpdatePriority.Normal)
        {
            return new CollectionUpdateOperation(collection, CollectionUpdateType.AddRange, items, priority);
        }

        /// <summary>
        /// 创建集合批量删除操作
        /// </summary>
        /// <param name="collection">目标集合</param>
        /// <param name="items">要删除的项目集合</param>
        /// <param name="priority">操作优先级</param>
        /// <returns>集合更新操作</returns>
        public static CollectionUpdateOperation RemoveRangeFromCollection(object collection, IEnumerable<object> items, UIUpdatePriority priority = UIUpdatePriority.Normal)
        {
            return new CollectionUpdateOperation(collection, CollectionUpdateType.RemoveRange, items, priority);
        }

        #endregion

        #region 复合操作工厂方法

        /// <summary>
        /// 创建ViewModel数据刷新操作集合
        /// </summary>
        /// <param name="viewModel">目标ViewModel</param>
        /// <param name="propertyNames">要刷新的属性名称</param>
        /// <param name="priority">操作优先级</param>
        /// <returns>UI更新操作集合</returns>
        public static IEnumerable<IUIUpdate> RefreshViewModelData(INotifyPropertyChanged viewModel, IEnumerable<string> propertyNames, UIUpdatePriority priority = UIUpdatePriority.Normal)
        {
            if (viewModel == null || propertyNames == null)
            {
                return Enumerable.Empty<IUIUpdate>();
            }

            var operations = new List<IUIUpdate>();

            foreach (var propertyName in propertyNames)
            {
                operations.Add(new ViewModelRefreshOperation(viewModel, propertyName, priority));
            }

            return operations;
        }

        /// <summary>
        /// 创建数据绑定重新绑定操作
        /// </summary>
        /// <param name="control">目标控件</param>
        /// <param name="propertyName">属性名称</param>
        /// <param name="dataSource">数据源</param>
        /// <param name="dataMember">数据成员</param>
        /// <param name="priority">操作优先级</param>
        /// <returns>数据绑定更新操作</returns>
        public static DataBindingUpdateOperation UpdateDataBinding(object control, string propertyName, object dataSource, string dataMember = null, UIUpdatePriority priority = UIUpdatePriority.Normal)
        {
            return new DataBindingUpdateOperation(control, propertyName, dataSource, dataMember, priority);
        }

        /// <summary>
        /// 创建控件状态更新操作
        /// </summary>
        /// <param name="control">目标控件</param>
        /// <param name="enabled">是否启用</param>
        /// <param name="visible">是否可见</param>
        /// <param name="priority">操作优先级</param>
        /// <returns>控件状态更新操作</returns>
        public static ControlStateUpdateOperation UpdateControlState(object control, bool? enabled = null, bool? visible = null, UIUpdatePriority priority = UIUpdatePriority.Normal)
        {
            return new ControlStateUpdateOperation(control, enabled, visible, priority);
        }

        #endregion

        #region 批量操作工厂方法

        /// <summary>
        /// 创建UI状态完全重置操作集合
        /// </summary>
        /// <param name="targetObject">目标对象</param>
        /// <param name="resetData">重置数据</param>
        /// <param name="priority">操作优先级</param>
        /// <returns>UI更新操作集合</returns>
        public static IEnumerable<IUIUpdate> ResetUIState(object targetObject, object resetData, UIUpdatePriority priority = UIUpdatePriority.High)
        {
            var operations = new List<IUIUpdate>();

            if (targetObject == null || resetData == null)
            {
                return operations;
            }

            try
            {
                // 获取重置数据的所有属性
                var properties = TypeDescriptor.GetProperties(resetData);
                
                foreach (PropertyDescriptor property in properties)
                {
                    var value = property.GetValue(resetData);
                    operations.Add(new PropertyUpdateOperation(targetObject, property.Name, value, priority));
                }

                LogManager.Info($"[UIUpdateFactory] 创建UI状态重置操作，共{operations.Count}个属性更新");
            }
            catch (Exception ex)
            {
                LogManager.Error("[UIUpdateFactory] 创建UI状态重置操作时发生异常", ex);
            }

            return operations;
        }

        /// <summary>
        /// 创建UI元素批量显示/隐藏操作
        /// </summary>
        /// <param name="controls">控件集合</param>
        /// <param name="visible">是否可见</param>
        /// <param name="priority">操作优先级</param>
        /// <returns>UI更新操作集合</returns>
        public static IEnumerable<IUIUpdate> SetControlsVisibility(IEnumerable<object> controls, bool visible, UIUpdatePriority priority = UIUpdatePriority.Normal)
        {
            if (controls == null)
            {
                return Enumerable.Empty<IUIUpdate>();
            }

            return controls.Select(control => 
                new PropertyUpdateOperation(control, "Visible", visible, priority)
            );
        }

        /// <summary>
        /// 创建UI元素批量启用/禁用操作
        /// </summary>
        /// <param name="controls">控件集合</param>
        /// <param name="enabled">是否启用</param>
        /// <param name="priority">操作优先级</param>
        /// <returns>UI更新操作集合</returns>
        public static IEnumerable<IUIUpdate> SetControlsEnabled(IEnumerable<object> controls, bool enabled, UIUpdatePriority priority = UIUpdatePriority.Normal)
        {
            if (controls == null)
            {
                return Enumerable.Empty<IUIUpdate>();
            }

            return controls.Select(control => 
                new PropertyUpdateOperation(control, "Enabled", enabled, priority)
            );
        }

        #endregion

        #region 条件操作工厂方法

        /// <summary>
        /// 创建条件更新操作
        /// </summary>
        /// <param name="condition">条件函数</param>
        /// <param name="trueOperation">条件为真时执行的操作</param>
        /// <param name="falseOperation">条件为假时执行的操作（可选）</param>
        /// <param name="priority">操作优先级</param>
        /// <returns>条件更新操作</returns>
        public static ConditionalUpdateOperation CreateConditionalUpdate(Func<bool> condition, IUIUpdate trueOperation, IUIUpdate falseOperation = null, UIUpdatePriority priority = UIUpdatePriority.Normal)
        {
            return new ConditionalUpdateOperation(condition, trueOperation, falseOperation, priority);
        }

        /// <summary>
        /// 创建延迟更新操作
        /// </summary>
        /// <param name="delayMilliseconds">延迟时间（毫秒）</param>
        /// <param name="operation">要延迟执行的操作</param>
        /// <param name="priority">操作优先级</param>
        /// <returns>延迟更新操作</returns>
        public static DelayedUpdateOperation CreateDelayedUpdate(int delayMilliseconds, IUIUpdate operation, UIUpdatePriority priority = UIUpdatePriority.Normal)
        {
            return new DelayedUpdateOperation(delayMilliseconds, operation, priority);
        }

        #endregion

        #region 自定义操作工厂方法

        /// <summary>
        /// 创建自定义更新操作
        /// </summary>
        /// <param name="name">操作名称</param>
        /// <param name="executeAction">执行逻辑</param>
        /// <param name="rollbackAction">回滚逻辑（可选）</param>
        /// <param name="validateFunc">验证逻辑（可选）</param>
        /// <param name="priority">操作优先级</param>
        /// <param name="targetFramework">目标框架</param>
        /// <returns>自定义更新操作</returns>
        public static CustomUpdateOperation CreateCustomUpdate(
            string name,
            Func<UIUpdateContext, System.Threading.CancellationToken, System.Threading.Tasks.Task<UIUpdateResult>> executeAction,
            Func<UIUpdateContext, System.Threading.CancellationToken, System.Threading.Tasks.Task<UIUpdateResult>> rollbackAction = null,
            Func<UIUpdateContext, UIUpdateValidationResult> validateFunc = null,
            UIUpdatePriority priority = UIUpdatePriority.Normal,
            UIFrameworkType targetFramework = UIFrameworkType.Auto)
        {
            return new CustomUpdateOperation(name, executeAction, rollbackAction, validateFunc, priority, targetFramework);
        }

        /// <summary>
        /// 创建UI线程安全的Action包装操作
        /// </summary>
        /// <param name="name">操作名称</param>
        /// <param name="action">要执行的Action</param>
        /// <param name="priority">操作优先级</param>
        /// <param name="targetFramework">目标框架</param>
        /// <returns>Action包装更新操作</returns>
        public static ActionWrapperUpdateOperation WrapAction(
            string name,
            Action action,
            UIUpdatePriority priority = UIUpdatePriority.Normal,
            UIFrameworkType targetFramework = UIFrameworkType.Auto)
        {
            return new ActionWrapperUpdateOperation(name, action, priority, targetFramework);
        }

        /// <summary>
        /// 创建UI线程安全的Func包装操作
        /// </summary>
        /// <param name="name">操作名称</param>
        /// <param name="func">要执行的Func</param>
        /// <param name="priority">操作优先级</param>
        /// <param name="targetFramework">目标框架</param>
        /// <returns>Func包装更新操作</returns>
        public static FuncWrapperUpdateOperation<T> WrapFunc<T>(
            string name,
            Func<T> func,
            UIUpdatePriority priority = UIUpdatePriority.Normal,
            UIFrameworkType targetFramework = UIFrameworkType.Auto)
        {
            return new FuncWrapperUpdateOperation<T>(name, func, priority, targetFramework);
        }

        #endregion

        #region 链式操作工厂方法

        /// <summary>
        /// 创建操作链
        /// </summary>
        /// <param name="name">操作链名称</param>
        /// <param name="operations">操作集合</param>
        /// <param name="priority">操作优先级</param>
        /// <returns>操作链更新操作</returns>
        public static ChainedUpdateOperation CreateOperationChain(string name, IEnumerable<IUIUpdate> operations, UIUpdatePriority priority = UIUpdatePriority.Normal)
        {
            return new ChainedUpdateOperation(name, operations, priority);
        }

        /// <summary>
        /// 创建并行操作组
        /// </summary>
        /// <param name="name">操作组名称</param>
        /// <param name="operations">操作集合</param>
        /// <param name="priority">操作优先级</param>
        /// <returns>并行操作组更新操作</returns>
        public static ParallelUpdateOperation CreateParallelOperation(string name, IEnumerable<IUIUpdate> operations, UIUpdatePriority priority = UIUpdatePriority.Normal)
        {
            return new ParallelUpdateOperation(name, operations, priority);
        }

        #endregion
    }
}