using System.Diagnostics;

namespace NavisworksTransport.Core.UIUpdate
{
    /// <summary>
    /// UI更新操作基类
    /// 提供UI更新操作的通用功能和标准实现
    /// </summary>
    public abstract class UIUpdateBase : IUIUpdate
    {
        #region 字段和属性

        /// <summary>
        /// 更新操作的唯一标识符
        /// </summary>
        public string Id { get; private set; }

        /// <summary>
        /// 更新操作名称
        /// </summary>
        public string Name { get; protected set; }

        /// <summary>
        /// 更新操作描述
        /// </summary>
        public string Description { get; protected set; }

        /// <summary>
        /// 操作优先级
        /// </summary>
        public UIUpdatePriority Priority { get; protected set; }

        /// <summary>
        /// 目标UI框架类型
        /// </summary>
        public UIFrameworkType TargetFramework { get; protected set; }

        /// <summary>
        /// 是否需要在UI线程上执行
        /// </summary>
        public virtual bool RequiresUIThread { get; protected set; } = true;

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreatedTime { get; private set; }

        /// <summary>
        /// 最后执行时间
        /// </summary>
        public DateTime? LastExecutedTime { get; private set; }

        /// <summary>
        /// 执行次数
        /// </summary>
        public int ExecutionCount { get; private set; }

        /// <summary>
        /// 是否支持回滚
        /// </summary>
        public virtual bool SupportsRollback { get; protected set; } = false;

        #endregion

        #region 构造函数

        /// <summary>
        /// 初始化UI更新操作基类
        /// </summary>
        protected UIUpdateBase()
        {
            Id = Guid.NewGuid().ToString();
            Name = GetType().Name;
            Description = "UI更新操作";
            Priority = UIUpdatePriority.Normal;
            TargetFramework = UIFrameworkType.Auto;
            CreatedTime = DateTime.UtcNow;
        }

        /// <summary>
        /// 初始化UI更新操作基类
        /// </summary>
        /// <param name="name">操作名称</param>
        /// <param name="description">操作描述</param>
        /// <param name="priority">操作优先级</param>
        /// <param name="targetFramework">目标UI框架</param>
        protected UIUpdateBase(string name, string description = null, UIUpdatePriority priority = UIUpdatePriority.Normal, UIFrameworkType targetFramework = UIFrameworkType.Auto)
        {
            Id = Guid.NewGuid().ToString();
            Name = name ?? GetType().Name;
            Description = description ?? "UI更新操作";
            Priority = priority;
            TargetFramework = targetFramework;
            CreatedTime = DateTime.UtcNow;
        }

        #endregion

        #region IUIUpdate接口实现

        /// <summary>
        /// 验证更新操作是否可以执行
        /// </summary>
        /// <param name="context">更新上下文</param>
        /// <returns>验证结果</returns>
        public virtual UIUpdateValidationResult Validate(UIUpdateContext context)
        {
            try
            {
                // 基础验证
                if (context == null)
                {
                    return UIUpdateValidationResult.Failure("更新上下文不能为空");
                }

                // 框架兼容性验证
                if (TargetFramework != UIFrameworkType.Auto && 
                    context.TargetFramework != UIFrameworkType.Auto &&
                    TargetFramework != context.TargetFramework)
                {
                    return UIUpdateValidationResult.Failure($"UI框架不兼容，更新操作需要{TargetFramework}，但上下文指定了{context.TargetFramework}");
                }

                // 调用子类的具体验证逻辑
                return ValidateInternal(context);
            }
            catch (Exception ex)
            {
                LogManager.Error($"[UIUpdate] 验证更新操作{Name}时发生异常: {ex.Message}", ex);
                return UIUpdateValidationResult.Failure($"验证时发生异常: {ex.Message}");
            }
        }

        /// <summary>
        /// 执行UI更新操作
        /// </summary>
        /// <param name="context">更新上下文</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>执行结果</returns>
        public async Task<UIUpdateResult> ExecuteAsync(UIUpdateContext context, CancellationToken cancellationToken = default)
        {
            var stopwatch = Stopwatch.StartNew();
            
            try
            {
                LogManager.Info($"[UIUpdate] 开始执行UI更新操作: {Name}");

                // 验证操作
                var validationResult = Validate(context);
                if (!validationResult.IsValid)
                {
                    return UIUpdateResult.Failure($"验证失败: {validationResult.Message}", null, Id);
                }

                // 检查取消令牌
                cancellationToken.ThrowIfCancellationRequested();

                // 执行前置处理
                var preResult = await PreExecuteAsync(context, cancellationToken);
                if (!preResult.IsSuccess)
                {
                    return preResult;
                }

                // 执行主要逻辑
                var result = await ExecuteInternalAsync(context, cancellationToken);
                
                // 执行后置处理
                if (result.IsSuccess)
                {
                    var postResult = await PostExecuteAsync(context, cancellationToken);
                    if (!postResult.IsSuccess)
                    {
                        // 后置处理失败，尝试回滚主要操作
                        if (SupportsRollback)
                        {
                            try
                            {
                                await RollbackAsync(context, cancellationToken);
                            }
                            catch (Exception rollbackEx)
                            {
                                LogManager.Error($"[UIUpdate] 回滚操作{Name}时发生异常: {rollbackEx.Message}", rollbackEx);
                            }
                        }
                        return postResult;
                    }
                }

                // 更新执行统计
                ExecutionCount++;
                LastExecutedTime = DateTime.UtcNow;
                result.ElapsedMilliseconds = stopwatch.ElapsedMilliseconds;
                result.UpdateId = Id;

                LogManager.Info($"[UIUpdate] UI更新操作{Name}执行完成，耗时{stopwatch.ElapsedMilliseconds}ms，结果: {(result.IsSuccess ? "成功" : "失败")}");
                
                return result;
            }
            catch (OperationCanceledException)
            {
                LogManager.Warning($"[UIUpdate] UI更新操作{Name}被取消");
                return UIUpdateResult.Failure("操作被取消", null, Id);
            }
            catch (Exception ex)
            {
                LogManager.Error($"[UIUpdate] 执行UI更新操作{Name}时发生异常: {ex.Message}", ex);
                return UIUpdateResult.Failure($"执行失败: {ex.Message}", ex, Id);
            }
            finally
            {
                stopwatch.Stop();
            }
        }

        /// <summary>
        /// 回滚UI更新操作（如果支持）
        /// </summary>
        /// <param name="context">更新上下文</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>回滚结果</returns>
        public virtual async Task<UIUpdateResult> RollbackAsync(UIUpdateContext context, CancellationToken cancellationToken = default)
        {
            if (!SupportsRollback)
            {
                return UIUpdateResult.Failure("此更新操作不支持回滚", null, Id);
            }

            try
            {
                LogManager.Info($"[UIUpdate] 开始回滚UI更新操作: {Name}");
                
                var result = await RollbackInternalAsync(context, cancellationToken);
                
                LogManager.Info($"[UIUpdate] UI更新操作{Name}回滚完成，结果: {(result.IsSuccess ? "成功" : "失败")}");
                
                return result;
            }
            catch (Exception ex)
            {
                LogManager.Error($"[UIUpdate] 回滚UI更新操作{Name}时发生异常: {ex.Message}", ex);
                return UIUpdateResult.Failure($"回滚失败: {ex.Message}", ex, Id);
            }
        }

        #endregion

        #region 受保护的虚拟方法

        /// <summary>
        /// 内部验证逻辑（子类可重写）
        /// </summary>
        /// <param name="context">更新上下文</param>
        /// <returns>验证结果</returns>
        protected virtual UIUpdateValidationResult ValidateInternal(UIUpdateContext context)
        {
            return UIUpdateValidationResult.Success();
        }

        /// <summary>
        /// 执行前置处理（子类可重写）
        /// </summary>
        /// <param name="context">更新上下文</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>处理结果</returns>
        protected virtual async Task<UIUpdateResult> PreExecuteAsync(UIUpdateContext context, CancellationToken cancellationToken)
        {
            return await Task.FromResult(UIUpdateResult.Success("前置处理完成", Id));
        }

        /// <summary>
        /// 执行主要逻辑（子类必须实现）
        /// </summary>
        /// <param name="context">更新上下文</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>执行结果</returns>
        protected abstract Task<UIUpdateResult> ExecuteInternalAsync(UIUpdateContext context, CancellationToken cancellationToken);

        /// <summary>
        /// 执行后置处理（子类可重写）
        /// </summary>
        /// <param name="context">更新上下文</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>处理结果</returns>
        protected virtual async Task<UIUpdateResult> PostExecuteAsync(UIUpdateContext context, CancellationToken cancellationToken)
        {
            return await Task.FromResult(UIUpdateResult.Success("后置处理完成", Id));
        }

        /// <summary>
        /// 内部回滚逻辑（子类可重写）
        /// </summary>
        /// <param name="context">更新上下文</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>回滚结果</returns>
        protected virtual async Task<UIUpdateResult> RollbackInternalAsync(UIUpdateContext context, CancellationToken cancellationToken)
        {
            return await Task.FromResult(UIUpdateResult.Failure("基类不支持回滚操作", null, Id));
        }

        #endregion

        #region 受保护的辅助方法

        /// <summary>
        /// 检查取消令牌
        /// </summary>
        /// <param name="cancellationToken">取消令牌</param>
        protected void ThrowIfCancellationRequested(CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
        }

        /// <summary>
        /// 记录信息日志
        /// </summary>
        /// <param name="message">日志消息</param>
        protected void LogInfo(string message)
        {
            LogManager.Info($"[UIUpdate:{Name}] {message}");
        }

        /// <summary>
        /// 记录警告日志
        /// </summary>
        /// <param name="message">日志消息</param>
        protected void LogWarning(string message)
        {
            LogManager.Warning($"[UIUpdate:{Name}] {message}");
        }

        /// <summary>
        /// 记录错误日志
        /// </summary>
        /// <param name="message">日志消息</param>
        /// <param name="exception">异常对象</param>
        protected void LogError(string message, Exception exception = null)
        {
            LogManager.Error($"[UIUpdate:{Name}] {message}", exception);
        }

        #endregion

        #region 重写方法

        /// <summary>
        /// 获取字符串表示
        /// </summary>
        public override string ToString()
        {
            return $"{Name} ({Id}) - {Priority} - {TargetFramework}";
        }

        /// <summary>
        /// 获取哈希码
        /// </summary>
        public override int GetHashCode()
        {
            return Id.GetHashCode();
        }

        /// <summary>
        /// 比较是否相等
        /// </summary>
        public override bool Equals(object obj)
        {
            if (obj is UIUpdateBase other)
            {
                return Id.Equals(other.Id);
            }
            return false;
        }

        #endregion
    }
}