using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using NavisworksTransport.Core;

namespace NavisworksTransport.Commands
{
    /// <summary>
    /// 命令执行器
    /// 提供异步命令执行框架，与UIStateManager集成，支持命令队列和状态跟踪
    /// </summary>
    public class CommandExecutor
    {
        #region 字段和属性

        private static CommandExecutor _instance;
        private static readonly object _instanceLock = new object();

        private readonly ConcurrentDictionary<string, IPathPlanningCommand> _runningCommands;
        private readonly ConcurrentQueue<CommandExecutionRequest> _commandQueue;
        private readonly SemaphoreSlim _executionSemaphore;
        private readonly UIStateManager _uiStateManager;
        private volatile bool _isProcessing = false;
        private volatile bool _isDisposed = false;

        /// <summary>
        /// 获取CommandExecutor的单例实例
        /// </summary>
        public static CommandExecutor Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (_instanceLock)
                    {
                        if (_instance == null)
                        {
                            _instance = new CommandExecutor();
                        }
                    }
                }
                return _instance;
            }
        }

        /// <summary>
        /// 当前正在运行的命令数量
        /// </summary>
        public int RunningCommandCount => _runningCommands.Count;

        /// <summary>
        /// 队列中等待执行的命令数量
        /// </summary>
        public int QueuedCommandCount => _commandQueue.Count;

        /// <summary>
        /// 最大并发执行命令数
        /// </summary>
        public int MaxConcurrentCommands { get; set; } = 3;

        #endregion

        #region 事件

        /// <summary>
        /// 命令开始执行事件
        /// </summary>
        public event EventHandler<CommandExecutionEventArgs> CommandStarted;

        /// <summary>
        /// 命令执行完成事件
        /// </summary>
        public event EventHandler<CommandCompletedEventArgs> CommandCompleted;

        /// <summary>
        /// 队列状态改变事件
        /// </summary>
        public event EventHandler<QueueStatusEventArgs> QueueStatusChanged;

        #endregion

        #region 构造函数

        private CommandExecutor()
        {
            _runningCommands = new ConcurrentDictionary<string, IPathPlanningCommand>();
            _commandQueue = new ConcurrentQueue<CommandExecutionRequest>();
            _executionSemaphore = new SemaphoreSlim(MaxConcurrentCommands, MaxConcurrentCommands);
            _uiStateManager = UIStateManager.Instance;

            LogManager.Info("CommandExecutor 初始化完成");
        }

        #endregion

        #region 公共方法

        /// <summary>
        /// 执行单个命令（异步）
        /// </summary>
        public async Task<PathPlanningResult> ExecuteAsync(IPathPlanningCommand command, CancellationToken cancellationToken = default)
        {
            if (command == null)
            {
                return PathPlanningResult.Failure("命令对象不能为空");
            }

            if (_isDisposed)
            {
                return PathPlanningResult.Failure("CommandExecutor已被释放");
            }

            try
            {
                LogManager.Info($"开始执行命令: {command.DisplayName} (ID: {command.CommandId})");

                // 等待执行槽位
                await _executionSemaphore.WaitAsync(cancellationToken);

                try
                {
                    // 添加到运行命令列表
                    _runningCommands.TryAdd(command.CommandId, command);

                    // 触发命令开始事件
                    OnCommandStarted(command);

                    // 订阅命令状态改变事件
                    command.StatusChanged += OnCommandStatusChanged;
                    command.ProgressChanged += OnCommandProgressChanged;

                    // 执行命令
                    var result = await command.ExecuteAsync(cancellationToken);

                    // 触发命令完成事件
                    OnCommandCompleted(command, result);

                    LogManager.Info($"命令执行完成: {command.DisplayName}, 结果: {(result.IsSuccess ? "成功" : "失败")}");

                    return result;
                }
                finally
                {
                    // 从运行命令列表中移除
                    _runningCommands.TryRemove(command.CommandId, out _);

                    // 取消订阅事件
                    command.StatusChanged -= OnCommandStatusChanged;
                    command.ProgressChanged -= OnCommandProgressChanged;

                    // 释放执行槽位
                    _executionSemaphore.Release();
                }
            }
            catch (OperationCanceledException)
            {
                LogManager.Info($"命令执行被取消: {command.DisplayName}");
                return PathPlanningResult.Failure("命令执行已取消");
            }
            catch (Exception ex)
            {
                LogManager.Error($"执行命令时出现异常: {command.DisplayName}", ex);
                return PathPlanningResult.Failure($"命令执行异常: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 将命令加入队列异步执行
        /// </summary>
        public Task<PathPlanningResult> EnqueueAsync(IPathPlanningCommand command, 
                                                   CommandPriority priority = CommandPriority.Normal,
                                                   CancellationToken cancellationToken = default)
        {
            if (command == null)
            {
                return Task.FromResult(PathPlanningResult.Failure("命令对象不能为空"));
            }

            if (_isDisposed)
            {
                return Task.FromResult(PathPlanningResult.Failure("CommandExecutor已被释放"));
            }

            var request = new CommandExecutionRequest
            {
                Command = command,
                Priority = priority,
                CancellationToken = cancellationToken,
                TaskCompletionSource = new TaskCompletionSource<PathPlanningResult>()
            };

            _commandQueue.Enqueue(request);
            OnQueueStatusChanged();

            // 启动处理队列（直接在主线程执行，避免后台线程导致的Navisworks Native对象生命周期问题）
            ProcessQueueAsync();

            LogManager.Info($"命令已加入队列: {command.DisplayName} (优先级: {priority})");

            return request.TaskCompletionSource.Task;
        }

        /// <summary>
        /// 取消指定命令
        /// </summary>
        public bool CancelCommand(string commandId)
        {
            if (_runningCommands.TryGetValue(commandId, out var command))
            {
                command.Cancel();
                LogManager.Info($"已发送取消请求: {command.DisplayName}");
                return true;
            }

            LogManager.Warning($"未找到要取消的命令: {commandId}");
            return false;
        }

        /// <summary>
        /// 取消所有正在运行的命令
        /// </summary>
        public void CancelAllCommands()
        {
            var commands = _runningCommands.Values.ToArray();
            foreach (var command in commands)
            {
                command.Cancel();
            }

            LogManager.Info($"已发送取消请求给 {commands.Length} 个命令");
        }

        /// <summary>
        /// 获取指定命令的状态
        /// </summary>
        public CommandExecutionStatus? GetCommandStatus(string commandId)
        {
            return _runningCommands.TryGetValue(commandId, out var command) ? (CommandExecutionStatus?)command.Status : null;
        }

        /// <summary>
        /// 获取所有正在运行的命令信息
        /// </summary>
        public IEnumerable<CommandInfo> GetRunningCommands()
        {
            return _runningCommands.Values.Select(cmd => new CommandInfo
            {
                CommandId = cmd.CommandId,
                DisplayName = cmd.DisplayName,
                Description = cmd.Description,
                Status = cmd.Status,
                Progress = cmd.Progress
            }).ToArray();
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            if (_isDisposed) return;

            _isDisposed = true;

            // 取消所有命令
            CancelAllCommands();

            // 等待所有命令完成（最多等待5秒）
            var timeout = TimeSpan.FromSeconds(5);
            var startTime = DateTime.Now;

            while (_runningCommands.Count > 0 && DateTime.Now - startTime < timeout)
            {
                Thread.Sleep(100);
            }

            _executionSemaphore?.Dispose();

            LogManager.Info("CommandExecutor 已释放");
        }

        #endregion

        #region 私有方法

        /// <summary>
        /// 处理命令队列
        /// </summary>
        private async Task ProcessQueueAsync()
        {
            if (_isProcessing || _isDisposed) return;

            _isProcessing = true;

            try
            {
                while (_commandQueue.TryDequeue(out var request) && !_isDisposed)
                {
                    try
                    {
                        var result = await ExecuteAsync(request.Command, request.CancellationToken);
                        request.TaskCompletionSource.SetResult(result);
                    }
                    catch (Exception ex)
                    {
                        var errorResult = PathPlanningResult.Failure($"队列执行命令失败: {ex.Message}", ex);
                        request.TaskCompletionSource.SetResult(errorResult);
                    }

                    OnQueueStatusChanged();
                }
            }
            finally
            {
                _isProcessing = false;
            }
        }

        #endregion

        #region 事件处理

        /// <summary>
        /// 处理命令状态改变事件，更新UI
        /// </summary>
        private void OnCommandStatusChanged(object sender, CommandStatusChangedEventArgs e)
        {
            if (!(sender is IPathPlanningCommand command)) return;

            // 使用UIStateManager安全更新UI
            _uiStateManager.QueueUIUpdate(() =>
            {
                LogManager.Info($"命令状态改变: {command.DisplayName} - {e.PreviousStatus} → {e.CurrentStatus}");
            }, UIUpdatePriority.Normal);
        }

        /// <summary>
        /// 处理命令进度改变事件，更新UI
        /// </summary>
        private void OnCommandProgressChanged(object sender, CommandProgressChangedEventArgs e)
        {
            if (!(sender is IPathPlanningCommand command)) return;

            // 使用UIStateManager安全更新UI
            _uiStateManager.QueueUIUpdate(() =>
            {
                // UI可以通过订阅CommandExecutor的事件来更新进度条
            }, UIUpdatePriority.Normal);
        }

        /// <summary>
        /// 触发命令开始事件
        /// </summary>
        private void OnCommandStarted(IPathPlanningCommand command)
        {
            try
            {
                CommandStarted?.Invoke(this, new CommandExecutionEventArgs(command));
            }
            catch (Exception ex)
            {
                LogManager.Error("触发命令开始事件时出现异常", ex);
            }
        }

        /// <summary>
        /// 触发命令完成事件
        /// </summary>
        private void OnCommandCompleted(IPathPlanningCommand command, PathPlanningResult result)
        {
            try
            {
                CommandCompleted?.Invoke(this, new CommandCompletedEventArgs(command, result));
            }
            catch (Exception ex)
            {
                LogManager.Error("触发命令完成事件时出现异常", ex);
            }
        }

        /// <summary>
        /// 触发队列状态改变事件
        /// </summary>
        private void OnQueueStatusChanged()
        {
            try
            {
                QueueStatusChanged?.Invoke(this, new QueueStatusEventArgs(QueuedCommandCount, RunningCommandCount));
            }
            catch (Exception ex)
            {
                LogManager.Error("触发队列状态改变事件时出现异常", ex);
            }
        }

        #endregion
    }

    #region 辅助类和枚举

    /// <summary>
    /// 命令优先级
    /// </summary>
    public enum CommandPriority
    {
        Low = 0,
        Normal = 1,
        High = 2,
        Critical = 3
    }

    /// <summary>
    /// 命令执行请求
    /// </summary>
    internal class CommandExecutionRequest
    {
        public IPathPlanningCommand Command { get; set; }
        public CommandPriority Priority { get; set; }
        public CancellationToken CancellationToken { get; set; }
        public TaskCompletionSource<PathPlanningResult> TaskCompletionSource { get; set; }
    }

    /// <summary>
    /// 命令信息
    /// </summary>
    public class CommandInfo
    {
        public string CommandId { get; set; }
        public string DisplayName { get; set; }
        public string Description { get; set; }
        public CommandExecutionStatus Status { get; set; }
        public int Progress { get; set; }
    }

    /// <summary>
    /// 命令执行事件参数
    /// </summary>
    public class CommandExecutionEventArgs : EventArgs
    {
        public IPathPlanningCommand Command { get; }

        public CommandExecutionEventArgs(IPathPlanningCommand command)
        {
            Command = command;
        }
    }

    /// <summary>
    /// 命令完成事件参数
    /// </summary>
    public class CommandCompletedEventArgs : EventArgs
    {
        public IPathPlanningCommand Command { get; }
        public PathPlanningResult Result { get; }

        public CommandCompletedEventArgs(IPathPlanningCommand command, PathPlanningResult result)
        {
            Command = command;
            Result = result;
        }
    }

    /// <summary>
    /// 队列状态事件参数
    /// </summary>
    public class QueueStatusEventArgs : EventArgs
    {
        public int QueuedCount { get; }
        public int RunningCount { get; }

        public QueueStatusEventArgs(int queuedCount, int runningCount)
        {
            QueuedCount = queuedCount;
            RunningCount = runningCount;
        }
    }

    #endregion
}