using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;

namespace NavisworksTransport.PathPlanning
{
    /// <summary>
    /// GridMap缓存项，包含网格地图和访问时间信息
    /// </summary>
    public class GridMapCacheItem
    {
        /// <summary>
        /// 缓存的网格地图
        /// </summary>
        public GridMap GridMap { get; set; }

        /// <summary>
        /// 最后访问时间
        /// </summary>
        public DateTime LastAccessTime { get; set; }

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

        /// <summary>
        /// 访问次数
        /// </summary>
        public int AccessCount { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        public GridMapCacheItem(GridMap gridMap)
        {
            GridMap = gridMap ?? throw new ArgumentNullException(nameof(gridMap));
            LastAccessTime = DateTime.Now;
            CreatedTime = DateTime.Now;
            AccessCount = 1;
        }

        /// <summary>
        /// 记录访问
        /// </summary>
        public void RecordAccess()
        {
            LastAccessTime = DateTime.Now;
            AccessCount++;
        }
    }

    /// <summary>
    /// GridMap缓存统计信息
    /// </summary>
    public class GridMapCacheStatistics
    {
        /// <summary>
        /// 缓存命中次数
        /// </summary>
        public long HitCount { get; set; }

        /// <summary>
        /// 缓存未命中次数
        /// </summary>
        public long MissCount { get; set; }

        /// <summary>
        /// 当前缓存项数量
        /// </summary>
        public int CurrentCount { get; set; }

        /// <summary>
        /// 最大缓存项数量
        /// </summary>
        public int MaxCapacity { get; set; }

        /// <summary>
        /// 被驱逐的缓存项数量
        /// </summary>
        public long EvictedCount { get; set; }

        /// <summary>
        /// 累计节省的构建时间（毫秒）
        /// </summary>
        public long TotalTimeSavedMs { get; set; }

        /// <summary>
        /// 缓存命中率
        /// </summary>
        public double HitRate => HitCount + MissCount > 0 ? (double)HitCount / (HitCount + MissCount) : 0.0;

        /// <summary>
        /// 缓存使用率
        /// </summary>
        public double UsageRate => MaxCapacity > 0 ? (double)CurrentCount / MaxCapacity : 0.0;

        /// <summary>
        /// 重置统计信息
        /// </summary>
        public void Reset()
        {
            HitCount = 0;
            MissCount = 0;
            EvictedCount = 0;
            TotalTimeSavedMs = 0;
        }

        /// <summary>
        /// 生成统计报告
        /// </summary>
        public string GenerateReport()
        {
            return $"GridMap缓存统计 - 命中率: {HitRate:P2} ({HitCount}命中/{MissCount}未命中), " +
                   $"使用率: {UsageRate:P2} ({CurrentCount}/{MaxCapacity}), " +
                   $"驱逐次数: {EvictedCount}, 节省时间: {TotalTimeSavedMs/1000.0:F1}秒";
        }
    }

    /// <summary>
    /// GridMap缓存管理器
    /// 使用LRU策略管理GridMap缓存，支持线程安全访问
    /// </summary>
    public class GridMapCache
    {
        private readonly ConcurrentDictionary<GridMapCacheKey, GridMapCacheItem> _cache;
        private readonly object _cleanupLock = new object();
        private readonly int _maxCapacity;
        private readonly GridMapCacheStatistics _statistics;

        /// <summary>
        /// 获取缓存统计信息
        /// </summary>
        public GridMapCacheStatistics Statistics => _statistics;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="maxCapacity">最大缓存容量，默认10个GridMap</param>
        public GridMapCache(int maxCapacity = 10)
        {
            if (maxCapacity <= 0)
                throw new ArgumentException("缓存容量必须大于0", nameof(maxCapacity));

            _maxCapacity = maxCapacity;
            _cache = new ConcurrentDictionary<GridMapCacheKey, GridMapCacheItem>();
            _statistics = new GridMapCacheStatistics { MaxCapacity = maxCapacity };

            LogManager.Info($"[GridMap缓存] 初始化完成，最大容量: {_maxCapacity}");
        }

        /// <summary>
        /// 获取缓存的GridMap
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <param name="estimatedBuildTimeMs">预估的构建时间（用于统计节省时间）</param>
        /// <returns>GridMap对象，如果不存在则返回null</returns>
        public GridMap Get(GridMapCacheKey key, long estimatedBuildTimeMs = 0)
        {
            if (key == null)
                return null;

            if (_cache.TryGetValue(key, out var item))
            {
                // 记录访问
                item.RecordAccess();
                _statistics.HitCount++;

                // 累计节省时间
                if (estimatedBuildTimeMs > 0)
                {
                    _statistics.TotalTimeSavedMs += estimatedBuildTimeMs;
                }

                LogManager.Info($"[GridMap缓存] 命中 - {key}，访问次数: {item.AccessCount}");
                return item.GridMap;
            }

            _statistics.MissCount++;
            LogManager.Info($"[GridMap缓存] 未命中 - {key}");
            return null;
        }

        /// <summary>
        /// 添加GridMap到缓存
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <param name="gridMap">GridMap对象</param>
        public void Put(GridMapCacheKey key, GridMap gridMap)
        {
            if (key == null || gridMap == null)
                return;

            var item = new GridMapCacheItem(gridMap);

            // 添加或更新缓存项
            _cache.AddOrUpdate(key, item, (k, existing) =>
            {
                LogManager.Debug($"[GridMap缓存] 更新现有项 - {key}");
                return item;
            });

            // 更新统计信息
            _statistics.CurrentCount = _cache.Count;

            LogManager.Info($"[GridMap缓存] 添加 - {key}，当前容量: {_cache.Count}/{_maxCapacity}");
            LogManager.Info($"[GridMap缓存] GridMap统计: {gridMap.GetStatistics()}");

            // 检查是否需要清理
            if (_cache.Count > _maxCapacity)
            {
                CleanupCache();
            }
        }

        /// <summary>
        /// 检查缓存中是否包含指定键
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <returns>是否包含</returns>
        public bool ContainsKey(GridMapCacheKey key)
        {
            return key != null && _cache.ContainsKey(key);
        }

        /// <summary>
        /// 清除所有缓存
        /// </summary>
        public void Clear()
        {
            lock (_cleanupLock)
            {
                var count = _cache.Count;
                _cache.Clear();
                _statistics.CurrentCount = 0;
                _statistics.Reset();

                LogManager.Info($"[GridMap缓存] 清除所有缓存，共清除 {count} 项");
            }
        }

        /// <summary>
        /// 获取缓存的所有键
        /// </summary>
        /// <returns>键列表</returns>
        public IList<GridMapCacheKey> GetKeys()
        {
            return _cache.Keys.ToList();
        }

        /// <summary>
        /// 清理缓存，使用LRU策略移除最少使用的项
        /// </summary>
        private void CleanupCache()
        {
            lock (_cleanupLock)
            {
                // 双重检查，避免重复清理
                if (_cache.Count <= _maxCapacity)
                    return;

                var targetCount = Math.Max(1, (int)(_maxCapacity * 0.7)); // 清理到70%容量
                var itemsToRemove = _cache.Count - targetCount;

                LogManager.Info($"[GridMap缓存] 开始LRU清理，当前: {_cache.Count}，目标: {targetCount}，需移除: {itemsToRemove}");

                // 按最后访问时间排序，移除最久未访问的项
                var sortedItems = _cache
                    .OrderBy(kvp => kvp.Value.LastAccessTime)
                    .ThenBy(kvp => kvp.Value.AccessCount) // 相同时间的情况下，优先移除访问次数少的
                    .Take(itemsToRemove)
                    .ToList();

                int removedCount = 0;
                foreach (var item in sortedItems)
                {
                    if (_cache.TryRemove(item.Key, out _))
                    {
                        removedCount++;
                        _statistics.EvictedCount++;
                        LogManager.Debug($"[GridMap缓存] 移除 - {item.Key}，最后访问: {item.Value.LastAccessTime:yyyy-MM-dd HH:mm:ss}");
                    }
                }

                _statistics.CurrentCount = _cache.Count;
                LogManager.Info($"[GridMap缓存] LRU清理完成，实际移除: {removedCount}，当前容量: {_cache.Count}");
            }
        }

        /// <summary>
        /// 生成缓存详细报告
        /// </summary>
        /// <returns>报告字符串</returns>
        public string GenerateDetailedReport()
        {
            var report = new System.Text.StringBuilder();

            report.AppendLine(_statistics.GenerateReport());

            if (_cache.Count > 0)
            {
                report.AppendLine($"\n当前缓存项详情:");
                var sortedItems = _cache
                    .OrderByDescending(kvp => kvp.Value.LastAccessTime)
                    .Take(5) // 只显示最近5项
                    .ToList();

                foreach (var item in sortedItems)
                {
                    var gridStats = item.Value.GridMap?.GetStatistics() ?? "N/A";
                    report.AppendLine($"  {item.Key}");
                    report.AppendLine($"    访问{item.Value.AccessCount}次，最后访问: {item.Value.LastAccessTime:MM-dd HH:mm:ss}");
                    report.AppendLine($"    GridMap: {gridStats}");
                }

                if (_cache.Count > 5)
                {
                    report.AppendLine($"  ... 还有 {_cache.Count - 5} 项");
                }
            }

            return report.ToString();
        }
    }

    /// <summary>
    /// 全局GridMap缓存管理器（单例）
    /// </summary>
    public static class GlobalGridMapCache
    {
        private static readonly Lazy<GridMapCache> _instance = new Lazy<GridMapCache>(() => new GridMapCache());

        /// <summary>
        /// 获取全局缓存实例
        /// </summary>
        public static GridMapCache Instance => _instance.Value;

        /// <summary>
        /// 重置全局缓存（主要用于测试）
        /// </summary>
        public static void Reset()
        {
            _instance.Value.Clear();
        }
    }
}