using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Navisworks.Api;

namespace NavisworksTransport.Core
{
    /// <summary>
    /// Idle事件统一管理器
    /// 提供基于Application.Idle事件的任务调度系统，改善UI性能
    /// </summary>
    public class IdleEventManager : IDisposable
    {
        #region 单例实现

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

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

        #endregion

        #region 私有字段

        private readonly Dictionary<string, IdleTask> _tasks = new Dictionary<string, IdleTask>();
        private readonly object _tasksLock = new object();
        private bool _isSubscribed = false;
        private bool _isDisposed = false;
        private DateTime _lastExecutionTime = DateTime.MinValue;

        #endregion

        #region 构造函数

        private IdleEventManager()
        {
            LogManager.Info("IdleEventManager 初始化");
        }

        #endregion

        #region 任务管理

        /// <summary>
        /// 注册持续任务
        /// </summary>
        /// <param name="taskId">任务ID</param>
        /// <param name="action">要执行的操作</param>
        /// <param name="minIntervalMs">最小执行间隔（毫秒）</param>
        /// <param name="priority">任务优先级（数字越大优先级越高）</param>
        public void RegisterTask(string taskId, Action action, double minIntervalMs = 0, int priority = 0)
        {
            if (string.IsNullOrEmpty(taskId))
                throw new ArgumentNullException(nameof(taskId));
            
            if (action == null)
                throw new ArgumentNullException(nameof(action));

            lock (_tasksLock)
            {
                _tasks[taskId] = new IdleTask
                {
                    TaskId = taskId,
                    Action = action,
                    MinInterval = minIntervalMs,
                    Priority = priority,
                    LastExecutionTime = DateTime.MinValue,
                    IsOneTime = false,
                    IsPaused = false,
                    Condition = null
                };

                EnsureSubscribed();
                LogManager.Info($"注册Idle任务: {taskId}, 间隔: {minIntervalMs}ms, 优先级: {priority}");
            }
        }

        /// <summary>
        /// 注册一次性任务（满足条件后执行一次）
        /// </summary>
        /// <param name="taskId">任务ID</param>
        /// <param name="condition">执行条件</param>
        /// <param name="action">要执行的操作</param>
        /// <param name="priority">任务优先级</param>
        public void RegisterOnceTask(string taskId, Func<bool> condition, Action action, int priority = 0)
        {
            if (string.IsNullOrEmpty(taskId))
                throw new ArgumentNullException(nameof(taskId));
            
            if (condition == null)
                throw new ArgumentNullException(nameof(condition));
            
            if (action == null)
                throw new ArgumentNullException(nameof(action));

            lock (_tasksLock)
            {
                _tasks[taskId] = new IdleTask
                {
                    TaskId = taskId,
                    Action = action,
                    MinInterval = 0,
                    Priority = priority,
                    LastExecutionTime = DateTime.MinValue,
                    IsOneTime = true,
                    IsPaused = false,
                    Condition = condition
                };

                EnsureSubscribed();
                LogManager.Info($"注册一次性Idle任务: {taskId}, 优先级: {priority}");
            }
        }

        /// <summary>
        /// 取消注册任务
        /// </summary>
        /// <param name="taskId">任务ID</param>
        public void UnregisterTask(string taskId)
        {
            lock (_tasksLock)
            {
                if (_tasks.Remove(taskId))
                {
                    LogManager.Info($"取消注册Idle任务: {taskId}");
                }

                if (_tasks.Count == 0)
                {
                    Unsubscribe();
                }
            }
        }

        /// <summary>
        /// 暂停任务
        /// </summary>
        /// <param name="taskId">任务ID</param>
        public void PauseTask(string taskId)
        {
            lock (_tasksLock)
            {
                if (_tasks.TryGetValue(taskId, out var task))
                {
                    task.IsPaused = true;
                    LogManager.Debug($"暂停Idle任务: {taskId}");
                }
            }
        }

        /// <summary>
        /// 恢复任务
        /// </summary>
        /// <param name="taskId">任务ID</param>
        public void ResumeTask(string taskId)
        {
            lock (_tasksLock)
            {
                if (_tasks.TryGetValue(taskId, out var task))
                {
                    task.IsPaused = false;
                    LogManager.Debug($"恢复Idle任务: {taskId}");
                }
            }
        }

        /// <summary>
        /// 获取当前注册的任务数量
        /// </summary>
        public int TaskCount
        {
            get
            {
                lock (_tasksLock)
                {
                    return _tasks.Count;
                }
            }
        }

        /// <summary>
        /// 获取活跃任务数量（未暂停的任务）
        /// </summary>
        public int ActiveTaskCount
        {
            get
            {
                lock (_tasksLock)
                {
                    return _tasks.Values.Count(t => !t.IsPaused);
                }
            }
        }

        #endregion

        #region Idle事件处理

        /// <summary>
        /// 确保已订阅Idle事件
        /// </summary>
        private void EnsureSubscribed()
        {
            if (!_isSubscribed && !_isDisposed)
            {
                try
                {
                    Application.Idle += OnApplicationIdle;
                    _isSubscribed = true;
                    LogManager.Debug("已订阅Application.Idle事件");
                }
                catch (Exception ex)
                {
                    LogManager.Error($"订阅Application.Idle事件失败: {ex.Message}");
                }
            }
        }

        /// <summary>
        /// 取消订阅Idle事件
        /// </summary>
        private void Unsubscribe()
        {
            if (_isSubscribed)
            {
                try
                {
                    Application.Idle -= OnApplicationIdle;
                    _isSubscribed = false;
                    LogManager.Debug("已取消订阅Application.Idle事件");
                }
                catch (Exception ex)
                {
                    LogManager.Error($"取消订阅Application.Idle事件失败: {ex.Message}");
                }
            }
        }

        /// <summary>
        /// Application.Idle事件处理器
        /// </summary>
        private void OnApplicationIdle(object sender, EventArgs e)
        {
            if (_isDisposed)
                return;

            var now = DateTime.Now;
            List<IdleTask> tasksToExecute = new List<IdleTask>();

            // 收集需要执行的任务
            lock (_tasksLock)
            {
                foreach (var task in _tasks.Values)
                {
                    if (task.IsPaused)
                        continue;

                    // 检查执行间隔
                    if ((now - task.LastExecutionTime).TotalMilliseconds < task.MinInterval)
                        continue;

                    // 对于一次性任务，检查条件
                    if (task.IsOneTime)
                    {
                        try
                        {
                            if (task.Condition != null && !task.Condition())
                                continue;
                        }
                        catch (Exception conditionEx)
                        {
                            LogManager.Error($"检查任务条件失败 [{task.TaskId}]: {conditionEx.Message}");
                            continue;
                        }
                    }

                    tasksToExecute.Add(task);
                }

                // 按优先级排序
                tasksToExecute = tasksToExecute.OrderByDescending(t => t.Priority).ToList();
            }

            // 执行任务（在锁外执行，避免死锁）
            var completedTasks = new List<string>();
            foreach (var task in tasksToExecute)
            {
                try
                {
                    task.Action();
                    task.LastExecutionTime = now;
                    
                    // 如果是一次性任务，标记为完成
                    if (task.IsOneTime)
                    {
                        completedTasks.Add(task.TaskId);
                    }

                    LogManager.Debug($"执行Idle任务: {task.TaskId}");
                }
                catch (Exception taskEx)
                {
                    LogManager.Error($"执行Idle任务失败 [{task.TaskId}]: {taskEx.Message}");
                }
            }

            // 移除已完成的一次性任务
            if (completedTasks.Count > 0)
            {
                lock (_tasksLock)
                {
                    foreach (var taskId in completedTasks)
                    {
                        _tasks.Remove(taskId);
                        LogManager.Info($"一次性Idle任务已完成: {taskId}");
                    }

                    if (_tasks.Count == 0)
                    {
                        Unsubscribe();
                    }
                }
            }

            _lastExecutionTime = now;
        }

        #endregion

        #region 工具方法

        /// <summary>
        /// 获取任务信息（用于调试）
        /// </summary>
        /// <returns>任务信息字符串</returns>
        public string GetTaskInfo()
        {
            lock (_tasksLock)
            {
                if (_tasks.Count == 0)
                    return "无活跃的Idle任务";

                var info = new System.Text.StringBuilder();
                info.AppendLine("=== Idle任务信息 ===");

                foreach (var task in _tasks.Values.OrderByDescending(t => t.Priority))
                {
                    var status = task.IsPaused ? "已暂停" : "活跃";
                    var type = task.IsOneTime ? "一次性" : "持续";
                    var lastRun = task.LastExecutionTime == DateTime.MinValue ? "未执行" : $"{(DateTime.Now - task.LastExecutionTime).TotalSeconds:F1}秒前";
                    
                    info.AppendLine($"任务: {task.TaskId}");
                    info.AppendLine($"  类型: {type}, 状态: {status}, 优先级: {task.Priority}");
                    info.AppendLine($"  间隔: {task.MinInterval}ms, 上次执行: {lastRun}");
                }

                info.AppendLine($"总任务数: {_tasks.Count}, 已订阅Idle事件: {_isSubscribed}");
                return info.ToString();
            }
        }

        #endregion

        #region IDisposable实现

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!_isDisposed)
            {
                if (disposing)
                {
                    try
                    {
                        // 取消订阅事件
                        Unsubscribe();

                        // 清理任务
                        lock (_tasksLock)
                        {
                            _tasks.Clear();
                        }

                        LogManager.Info("IdleEventManager 已释放资源");
                    }
                    catch (Exception ex)
                    {
                        LogManager.Error($"IdleEventManager 释放资源时发生异常: {ex.Message}");
                    }
                }

                _isDisposed = true;
            }
        }

        #endregion

        #region 内部类

        /// <summary>
        /// Idle任务信息
        /// </summary>
        private class IdleTask
        {
            public string TaskId { get; set; }
            public Action Action { get; set; }
            public double MinInterval { get; set; }
            public int Priority { get; set; }
            public DateTime LastExecutionTime { get; set; }
            public bool IsOneTime { get; set; }
            public bool IsPaused { get; set; }
            public Func<bool> Condition { get; set; }
        }

        #endregion
    }
}