using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace NavisworksTransport.Commands
{
    /// <summary>
    /// 命令抽象基类
    /// 提供公共的Command执行逻辑、统一的异常处理机制和执行状态管理
    /// </summary>
    public abstract class CommandBase : IPathPlanningCommand
    {
        #region 字段和属性

        private CommandExecutionStatus _status = CommandExecutionStatus.NotStarted;
        private int _progress = 0;
        private CancellationTokenSource _cancellationTokenSource;
        private readonly object _lockObject = new object();

        /// <summary>
        /// 命令的唯一标识符
        /// </summary>
        public virtual string CommandId { get; protected set; }

        /// <summary>
        /// 命令的显示名称
        /// </summary>
        public virtual string DisplayName { get; protected set; }

        /// <summary>
        /// 命令的描述信息
        /// </summary>
        public virtual string Description { get; protected set; }

        /// <summary>
        /// 命令当前的执行状态
        /// </summary>
        public CommandExecutionStatus Status
        {
            get
            {
                lock (_lockObject)
                {
                    return _status;
                }
            }
            private set
            {
                CommandExecutionStatus previousStatus;
                lock (_lockObject)
                {
                    previousStatus = _status;
                    _status = value;
                }
                
                if (previousStatus != value)
                {
                    OnStatusChanged(previousStatus, value);
                }
            }
        }

        /// <summary>
        /// 执行进度（0-100）
        /// </summary>
        public int Progress
        {
            get
            {
                lock (_lockObject)
                {
                    return _progress;
                }
            }
            private set
            {
                int newProgress = Math.Max(0, Math.Min(100, value));
                int oldProgress;
                
                lock (_lockObject)
                {
                    oldProgress = _progress;
                    _progress = newProgress;
                }
                
                if (oldProgress != newProgress)
                {
                    OnProgressChanged(newProgress);
                }
            }
        }

        #endregion

        #region 事件

        /// <summary>
        /// 当命令状态改变时触发的事件
        /// </summary>
        public event EventHandler<CommandStatusChangedEventArgs> StatusChanged;

        /// <summary>
        /// 当命令进度更新时触发的事件
        /// </summary>
        public event EventHandler<CommandProgressChangedEventArgs> ProgressChanged;

        #endregion

        #region 构造函数

        /// <summary>
        /// 初始化命令基类
        /// </summary>
        protected CommandBase()
        {
            CommandId = Guid.NewGuid().ToString();
            DisplayName = GetType().Name;
            Description = "路径规划命令";
        }

        /// <summary>
        /// 初始化命令基类
        /// </summary>
        protected CommandBase(string commandId, string displayName, string description = null)
        {
            CommandId = commandId ?? Guid.NewGuid().ToString();
            DisplayName = displayName ?? GetType().Name;
            Description = description ?? "路径规划命令";
        }

        #endregion

        #region 公共方法

        /// <summary>
        /// 异步执行命令
        /// </summary>
        public async Task<PathPlanningResult> ExecuteAsync(CancellationToken cancellationToken = default)
        {
            if (Status == CommandExecutionStatus.Executing)
            {
                return PathPlanningResult.Failure("命令正在执行中，请勿重复执行");
            }

            var stopwatch = Stopwatch.StartNew();
            
            try
            {
                // 创建内部取消令牌源，组合外部令牌
                _cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
                var combinedToken = _cancellationTokenSource.Token;

                // 验证阶段
                Status = CommandExecutionStatus.Validating;
                UpdateProgress(0, "正在验证命令参数...");

                var validationResult = await ValidateAsync(combinedToken);
                if (!validationResult.IsSuccess)
                {
                    Status = CommandExecutionStatus.Failed;
                    validationResult.ElapsedMilliseconds = stopwatch.ElapsedMilliseconds;
                    return validationResult;
                }

                // 执行阶段
                Status = CommandExecutionStatus.Executing;
                UpdateProgress(10, "开始执行命令...");

                var result = await ExecuteInternalAsync(combinedToken);
                
                // 设置执行时间
                result.ElapsedMilliseconds = stopwatch.ElapsedMilliseconds;

                // 根据结果设置状态
                if (combinedToken.IsCancellationRequested)
                {
                    Status = CommandExecutionStatus.Cancelled;
                    return PathPlanningResult.Failure("命令执行已取消");
                }
                else if (result.IsSuccess)
                {
                    Status = CommandExecutionStatus.Completed;
                    UpdateProgress(100, "命令执行完成");
                }
                else
                {
                    Status = CommandExecutionStatus.Failed;
                }

                return result;
            }
            catch (OperationCanceledException)
            {
                Status = CommandExecutionStatus.Cancelled;
                LogManager.Error($"命令 {DisplayName} 执行被取消");
                return PathPlanningResult.Failure("命令执行已取消");
            }
            catch (Exception ex)
            {
                Status = CommandExecutionStatus.Failed;
                LogManager.Error($"命令 {DisplayName} 执行出现异常", ex);
                return PathPlanningResult.Failure($"命令执行失败: {ex.Message}", ex);
            }
            finally
            {
                stopwatch.Stop();
                _cancellationTokenSource?.Dispose();
                _cancellationTokenSource = null;
            }
        }

        /// <summary>
        /// 验证命令是否可以执行
        /// </summary>
        public virtual PathPlanningResult CanExecute()
        {
            if (Status == CommandExecutionStatus.Executing)
            {
                return PathPlanningResult.ValidationFailure("命令正在执行中");
            }

            return ValidateParameters();
        }

        /// <summary>
        /// 取消命令执行
        /// </summary>
        public virtual void Cancel()
        {
            try
            {
                _cancellationTokenSource?.Cancel();
                LogManager.Info($"命令 {DisplayName} 取消请求已发送");
            }
            catch (Exception ex)
            {
                LogManager.Error($"取消命令 {DisplayName} 时出现异常", ex);
            }
        }

        #endregion

        #region 受保护方法

        /// <summary>
        /// 异步验证命令参数（可重写）
        /// </summary>
        protected virtual async Task<PathPlanningResult> ValidateAsync(CancellationToken cancellationToken)
        {
            return await Task.FromResult(ValidateParameters());
        }

        /// <summary>
        /// 验证命令参数（可重写）
        /// </summary>
        protected virtual PathPlanningResult ValidateParameters()
        {
            return PathPlanningResult.Success("参数验证通过");
        }

        /// <summary>
        /// 执行命令的核心逻辑（必须重写）
        /// </summary>
        protected abstract Task<PathPlanningResult> ExecuteInternalAsync(CancellationToken cancellationToken);

        /// <summary>
        /// 更新执行进度
        /// </summary>
        protected void UpdateProgress(int progress, string message = null)
        {
            int newProgress = Math.Max(0, Math.Min(100, progress));
            int oldProgress;
            
            lock (_lockObject)
            {
                oldProgress = _progress;
                _progress = newProgress;
            }
            
            if (oldProgress != newProgress)
            {
                OnProgressChanged(newProgress, message);
            }
            
            if (!string.IsNullOrEmpty(message))
            {
                try
                {
                    LogManager.Info($"{DisplayName}: {message} ({progress}%)");
                }
                catch
                {
                    // 在测试环境中LogManager可能未初始化，忽略异常
                    System.Diagnostics.Debug.WriteLine($"{DisplayName}: {message} ({progress}%)");
                }
            }
        }

        /// <summary>
        /// 检查取消令牌并抛出异常（如果已取消）
        /// </summary>
        protected void ThrowIfCancellationRequested(CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
        }

        /// <summary>
        /// 记录信息日志
        /// </summary>
        protected void LogInfo(string message)
        {
            try
            {
                LogManager.Info($"[{DisplayName}] {message}");
            }
            catch
            {
                // 在测试环境中LogManager可能未初始化，忽略异常
                System.Diagnostics.Debug.WriteLine($"[{DisplayName}] {message}");
            }
        }

        /// <summary>
        /// 记录错误日志
        /// </summary>
        protected void LogError(string message, Exception exception = null)
        {
            try
            {
                LogManager.Error($"[{DisplayName}] {message}", exception);
            }
            catch
            {
                // 在测试环境中LogManager可能未初始化，忽略异常
                System.Diagnostics.Debug.WriteLine($"[{DisplayName}] {message}");
                if (exception != null)
                {
                    System.Diagnostics.Debug.WriteLine($"Exception: {exception}");
                }
            }
        }

        /// <summary>
        /// 记录警告日志
        /// </summary>
        protected void LogWarning(string message)
        {
            try
            {
                LogManager.Warning($"[{DisplayName}] {message}");
            }
            catch
            {
                // 在测试环境中LogManager可能未初始化，忽略异常
                System.Diagnostics.Debug.WriteLine($"[{DisplayName}] {message}");
            }
        }

        #endregion

        #region 事件处理

        /// <summary>
        /// 触发状态改变事件
        /// </summary>
        protected virtual void OnStatusChanged(CommandExecutionStatus previousStatus, CommandExecutionStatus currentStatus, string message = null, Exception exception = null)
        {
            try
            {
                StatusChanged?.Invoke(this, new CommandStatusChangedEventArgs(previousStatus, currentStatus, message, exception));
            }
            catch (Exception ex)
            {
                LogManager.Error($"触发 {DisplayName} 状态改变事件时出现异常", ex);
            }
        }

        /// <summary>
        /// 触发进度改变事件
        /// </summary>
        protected virtual void OnProgressChanged(int progress, string message = null)
        {
            try
            {
                ProgressChanged?.Invoke(this, new CommandProgressChangedEventArgs(progress, message));
            }
            catch (Exception ex)
            {
                LogManager.Error($"触发 {DisplayName} 进度改变事件时出现异常", ex);
            }
        }

        #endregion
    }
}