//! 智能缓存管理系统
//! 提供多层缓存、智能过期策略和性能优化

use anyhow::{Result, anyhow};
use std::collections::{HashMap, BTreeMap, VecDeque};
use std::sync::Arc;
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
use std::hash::{Hash, Hasher};
use tokio::sync::{RwLock, Mutex};
use tokio::time::{sleep, interval};
use tracing::{info, warn, error, debug};
use serde::{Serialize, Deserialize};
use uuid::Uuid;

/// 缓存项
#[derive(Debug, Clone)]
pub struct CacheItem<T> {
    /// 数据
    pub data: T,
    /// 创建时间
    pub created_at: Instant,
    /// 最后访问时间
    pub last_accessed: Instant,
    /// 访问次数
    pub access_count: u64,
    /// 过期时间
    pub expires_at: Option<Instant>,
    /// 数据大小（字节）
    pub size: usize,
    /// 优先级
    pub priority: CachePriority,
}

/// 缓存优先级
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum CachePriority {
    /// 低优先级
    Low = 1,
    /// 普通优先级
    Normal = 2,
    /// 高优先级
    High = 3,
    /// 永不过期
    Permanent = 4,
}

/// 缓存策略
#[derive(Debug, Clone)]
pub enum EvictionPolicy {
    /// 最近最少使用
    LRU,
    /// 最不经常使用
    LFU,
    /// 先进先出
    FIFO,
    /// 基于时间的过期
    TTL,
    /// 智能策略（结合多种因素）
    Smart,
}

/// 缓存配置
#[derive(Debug, Clone)]
pub struct CacheConfig {
    /// 最大缓存大小（字节）
    pub max_size: usize,
    /// 最大缓存项数量
    pub max_items: usize,
    /// 默认过期时间
    pub default_ttl: Duration,
    /// 清理间隔
    pub cleanup_interval: Duration,
    /// 驱逐策略
    pub eviction_policy: EvictionPolicy,
    /// 是否启用统计
    pub enable_stats: bool,
    /// 预热阈值
    pub warmup_threshold: f64,
}

impl Default for CacheConfig {
    fn default() -> Self {
        Self {
            max_size: 100 * 1024 * 1024, // 100MB
            max_items: 10000,
            default_ttl: Duration::from_secs(3600), // 1小时
            cleanup_interval: Duration::from_secs(300), // 5分钟
            eviction_policy: EvictionPolicy::Smart,
            enable_stats: true,
            warmup_threshold: 0.8,
        }
    }
}

/// 缓存统计
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CacheStats {
    /// 总请求数
    pub total_requests: u64,
    /// 命中次数
    pub hits: u64,
    /// 未命中次数
    pub misses: u64,
    /// 命中率
    pub hit_rate: f64,
    /// 当前缓存项数量
    pub current_items: usize,
    /// 当前缓存大小
    pub current_size: usize,
    /// 最大缓存大小
    pub max_size: usize,
    /// 缓存利用率
    pub utilization: f64,
    /// 平均访问时间（微秒）
    pub average_access_time: f64,
    /// 驱逐次数
    pub evictions: u64,
    /// 过期次数
    pub expirations: u64,
}

/// 智能缓存管理器
pub struct CacheManager<K, V>
where
    K: Clone + Eq + Hash + Send + Sync + 'static,
    V: Clone + Send + Sync + 'static,
{
    /// 缓存存储
    cache: Arc<RwLock<HashMap<K, CacheItem<V>>>>,
    /// 访问顺序（用于 LRU）
    access_order: Arc<RwLock<BTreeMap<Instant, K>>>,
    /// 访问频率（用于 LFU）
    access_frequency: Arc<RwLock<BTreeMap<u64, Vec<K>>>>,
    /// 配置
    config: CacheConfig,
    /// 统计信息
    stats: Arc<RwLock<CacheStats>>,
    /// 清理任务句柄
    cleanup_handle: Arc<RwLock<Option<tokio::task::JoinHandle<()>>>>,
    /// 是否正在运行
    is_running: Arc<RwLock<bool>>,
}

impl<K, V> CacheManager<K, V>
where
    K: Clone + Eq + Hash + Send + Sync + 'static,
    V: Clone + Send + Sync + 'static,
{
    /// 创建新的缓存管理器
    pub fn new(config: CacheConfig) -> Self {
        Self {
            cache: Arc::new(RwLock::new(HashMap::new())),
            access_order: Arc::new(RwLock::new(BTreeMap::new())),
            access_frequency: Arc::new(RwLock::new(BTreeMap::new())),
            config,
            stats: Arc::new(RwLock::new(CacheStats {
                total_requests: 0,
                hits: 0,
                misses: 0,
                hit_rate: 0.0,
                current_items: 0,
                current_size: 0,
                max_size: 0,
                utilization: 0.0,
                average_access_time: 0.0,
                evictions: 0,
                expirations: 0,
            })),
            cleanup_handle: Arc::new(RwLock::new(None)),
            is_running: Arc::new(RwLock::new(false)),
        }
    }

    /// 启动缓存管理器
    pub async fn start(&self) -> Result<()> {
        info!("启动缓存管理器");

        // 检查是否已经在运行
        {
            let running = self.is_running.read().await;
            if *running {
                return Ok(());
            }
        }

        // 启动清理任务
        let cleanup_task = self.spawn_cleanup_task().await?;
        
        {
            let mut handle = self.cleanup_handle.write().await;
            *handle = Some(cleanup_task);
        }

        {
            let mut running = self.is_running.write().await;
            *running = true;
        }

        info!("缓存管理器已启动");
        Ok(())
    }

    /// 停止缓存管理器
    pub async fn stop(&self) -> Result<()> {
        info!("停止缓存管理器");

        let handle = {
            let mut handle_guard = self.cleanup_handle.write().await;
            handle_guard.take()
        };

        if let Some(handle) = handle {
            handle.abort();
        }

        {
            let mut running = self.is_running.write().await;
            *running = false;
        }

        info!("缓存管理器已停止");
        Ok(())
    }

    /// 获取缓存项
    pub async fn get(&self, key: &K) -> Option<V> {
        let start_time = Instant::now();

        let result = {
            let mut cache = self.cache.write().await;
            if let Some(item) = cache.get_mut(key) {
                // 检查是否过期
                if let Some(expires_at) = item.expires_at {
                    if Instant::now() > expires_at {
                        // 已过期，移除并返回 None
                        cache.remove(key);
                        self.update_stats_miss().await;
                        // TODO: 实现过期统计
                        // self.increment_expirations().await;
                        return None;
                    }
                }

                // 更新访问信息
                item.last_accessed = Instant::now();
                item.access_count += 1;

                // 更新访问跟踪
                self.update_access_tracking(key, item.access_count).await;

                let data = item.data.clone();
                self.update_stats_hit().await;
                Some(data)
            } else {
                self.update_stats_miss().await;
                None
            }
        };

        // 记录访问时间
        let access_time = start_time.elapsed().as_micros() as f64;
        self.update_average_access_time(access_time).await;

        result
    }

    /// 设置缓存项
    pub async fn set(&self, key: K, value: V, ttl: Option<Duration>, priority: CachePriority) -> Result<()> {
        let now = Instant::now();
        let expires_at = ttl.map(|t| now + t);

        // 估算数据大小（简化实现）
        let size = std::mem::size_of::<V>();

        let item = CacheItem {
            data: value,
            created_at: now,
            last_accessed: now,
            access_count: 0,
            expires_at,
            size,
            priority,
        };

        // 检查是否需要驱逐
        self.ensure_capacity(size).await?;

        {
            let mut cache = self.cache.write().await;
            cache.insert(key.clone(), item);
        }

        // 更新访问跟踪
        self.update_access_tracking(&key, 1).await;

        // 更新统计
        self.update_cache_stats().await;

        Ok(())
    }

    /// 移除缓存项
    pub async fn remove(&self, key: &K) -> Option<V> {
        let mut cache = self.cache.write().await;
        if let Some(item) = cache.remove(key) {
            self.update_cache_stats().await;
            Some(item.data)
        } else {
            None
        }
    }

    /// 清空缓存
    pub async fn clear(&self) -> Result<()> {
        {
            let mut cache = self.cache.write().await;
            cache.clear();
        }

        {
            let mut access_order = self.access_order.write().await;
            access_order.clear();
        }

        {
            let mut access_frequency = self.access_frequency.write().await;
            access_frequency.clear();
        }

        self.update_cache_stats().await;
        info!("缓存已清空");
        Ok(())
    }

    /// 获取缓存统计
    pub async fn get_stats(&self) -> CacheStats {
        self.stats.read().await.clone()
    }

    /// 获取缓存健康状态
    pub async fn get_health_status(&self) -> CacheHealthStatus {
        let stats = self.get_stats().await;
        let cache = self.cache.read().await;

        let status = if stats.hit_rate >= 0.8 {
            "excellent"
        } else if stats.hit_rate >= 0.6 {
            "good"
        } else if stats.hit_rate >= 0.4 {
            "fair"
        } else {
            "poor"
        };

        CacheHealthStatus {
            status: status.to_string(),
            hit_rate: stats.hit_rate,
            utilization: stats.utilization,
            total_items: cache.len(),
            expired_items: 0, // TODO: 实现过期项计数
            memory_usage: stats.current_size,
            recommendations: Vec::new(), // TODO: 实现推荐生成
        }
    }

    /// 检查是否正在运行
    pub async fn is_running(&self) -> bool {
        *self.is_running.read().await
    }





    /// 检查缓存容量并驱逐项目
    async fn ensure_capacity(&self, new_item_size: usize) -> Result<()> {
        let (current_size, current_items) = {
            let cache = self.cache.read().await;
            let size = cache.values().map(|item| item.size).sum::<usize>();
            (size, cache.len())
        };

        // 检查是否需要驱逐
        let needs_eviction = current_size + new_item_size > self.config.max_size
            || current_items >= self.config.max_items;

        if needs_eviction {
            self.evict_items(new_item_size).await?;
        }

        Ok(())
    }

    /// 驱逐缓存项
    async fn evict_items(&self, needed_space: usize) -> Result<()> {
        let mut freed_space = 0;
        let mut evicted_count = 0;

        match self.config.eviction_policy {
            EvictionPolicy::LRU => {
                self.evict_lru(&mut freed_space, &mut evicted_count, needed_space).await?;
            }
            EvictionPolicy::LFU => {
                self.evict_lfu(&mut freed_space, &mut evicted_count, needed_space).await?;
            }
            EvictionPolicy::FIFO => {
                self.evict_fifo(&mut freed_space, &mut evicted_count, needed_space).await?;
            }
            EvictionPolicy::TTL => {
                self.evict_expired(&mut freed_space, &mut evicted_count).await?;
            }
            EvictionPolicy::Smart => {
                self.evict_smart(&mut freed_space, &mut evicted_count, needed_space).await?;
            }
        }

        // 更新统计
        {
            let mut stats = self.stats.write().await;
            stats.evictions += evicted_count;
        }

        debug!("驱逐了 {} 个缓存项，释放了 {} 字节", evicted_count, freed_space);
        Ok(())
    }

    /// LRU 驱逐策略
    async fn evict_lru(&self, freed_space: &mut usize, evicted_count: &mut u64, needed_space: usize) -> Result<()> {
        let keys_to_evict = {
            let access_order = self.access_order.read().await;
            let cache = self.cache.read().await;
            
            let mut keys = Vec::new();
            let mut space = 0;
            
            for (_, key) in access_order.iter() {
                if let Some(item) = cache.get(key) {
                    if item.priority != CachePriority::Permanent {
                        keys.push(key.clone());
                        space += item.size;
                        if space >= needed_space {
                            break;
                        }
                    }
                }
            }
            keys
        };

        for key in keys_to_evict {
            if let Some(item) = self.remove(&key).await {
                *freed_space += std::mem::size_of_val(&item);
                *evicted_count += 1;
            }
        }

        Ok(())
    }

    /// LFU 驱逐策略
    async fn evict_lfu(&self, freed_space: &mut usize, evicted_count: &mut u64, needed_space: usize) -> Result<()> {
        let keys_to_evict = {
            let access_frequency = self.access_frequency.read().await;
            let cache = self.cache.read().await;
            
            let mut keys = Vec::new();
            let mut space = 0;
            
            for (_, key_list) in access_frequency.iter() {
                for key in key_list {
                    if let Some(item) = cache.get(key) {
                        if item.priority != CachePriority::Permanent {
                            keys.push(key.clone());
                            space += item.size;
                            if space >= needed_space {
                                break;
                            }
                        }
                    }
                }
                if space >= needed_space {
                    break;
                }
            }
            keys
        };

        for key in keys_to_evict {
            if let Some(item) = self.remove(&key).await {
                *freed_space += std::mem::size_of_val(&item);
                *evicted_count += 1;
            }
        }

        Ok(())
    }

    /// FIFO 驱逐策略
    async fn evict_fifo(&self, freed_space: &mut usize, evicted_count: &mut u64, needed_space: usize) -> Result<()> {
        let keys_to_evict = {
            let cache = self.cache.read().await;
            let mut items: Vec<_> = cache.iter()
                .filter(|(_, item)| item.priority != CachePriority::Permanent)
                .collect();
            
            items.sort_by_key(|(_, item)| item.created_at);
            
            let mut keys = Vec::new();
            let mut space = 0;
            
            for (key, item) in items {
                keys.push(key.clone());
                space += item.size;
                if space >= needed_space {
                    break;
                }
            }
            keys
        };

        for key in keys_to_evict {
            if let Some(item) = self.remove(&key).await {
                *freed_space += std::mem::size_of_val(&item);
                *evicted_count += 1;
            }
        }

        Ok(())
    }

    /// 智能驱逐策略
    async fn evict_smart(&self, freed_space: &mut usize, evicted_count: &mut u64, needed_space: usize) -> Result<()> {
        // 首先清理过期项
        self.evict_expired(freed_space, evicted_count).await?;
        
        if *freed_space >= needed_space {
            return Ok(());
        }

        // 然后使用综合评分驱逐
        let keys_to_evict = {
            let cache = self.cache.read().await;
            let now = Instant::now();
            
            let mut scored_items: Vec<_> = cache.iter()
                .filter(|(_, item)| item.priority != CachePriority::Permanent)
                .map(|(key, item)| {
                    // 计算综合评分（越低越容易被驱逐）
                    let age_score = now.duration_since(item.last_accessed).as_secs() as f64;
                    let frequency_score = 1.0 / (item.access_count as f64 + 1.0);
                    let priority_score = match item.priority {
                        CachePriority::Low => 1.0,
                        CachePriority::Normal => 2.0,
                        CachePriority::High => 4.0,
                        CachePriority::Permanent => f64::MAX,
                    };
                    
                    let score = age_score * frequency_score / priority_score;
                    (key.clone(), item.size, score)
                })
                .collect();
            
            scored_items.sort_by(|a, b| a.2.partial_cmp(&b.2).unwrap_or(std::cmp::Ordering::Equal));
            
            let mut keys = Vec::new();
            let mut space = *freed_space;
            
            for (key, size, _) in scored_items {
                keys.push(key);
                space += size;
                if space >= needed_space {
                    break;
                }
            }
            keys
        };

        for key in keys_to_evict {
            if let Some(item) = self.remove(&key).await {
                *freed_space += std::mem::size_of_val(&item);
                *evicted_count += 1;
            }
        }

        Ok(())
    }

    /// 清理过期项
    async fn evict_expired(&self, freed_space: &mut usize, evicted_count: &mut u64) -> Result<()> {
        let now = Instant::now();
        let expired_keys = {
            let cache = self.cache.read().await;
            cache.iter()
                .filter(|(_, item)| {
                    if let Some(expires_at) = item.expires_at {
                        now > expires_at
                    } else {
                        false
                    }
                })
                .map(|(key, _)| key.clone())
                .collect::<Vec<_>>()
        };

        for key in expired_keys {
            if let Some(item) = self.remove(&key).await {
                *freed_space += std::mem::size_of_val(&item);
                *evicted_count += 1;
            }
        }

        Ok(())
    }

    /// 更新访问跟踪
    async fn update_access_tracking(&self, key: &K, access_count: u64) {
        let now = Instant::now();

        // 更新访问顺序
        {
            let mut access_order = self.access_order.write().await;
            access_order.insert(now, key.clone());
        }

        // 更新访问频率
        {
            let mut access_frequency = self.access_frequency.write().await;
            access_frequency.entry(access_count).or_insert_with(Vec::new).push(key.clone());
        }
    }

    /// 清理访问跟踪
    async fn cleanup_access_tracking(&self, key: &K) {
        // 从访问顺序中移除
        {
            let mut access_order = self.access_order.write().await;
            access_order.retain(|_, k| k != key);
        }

        // 从访问频率中移除
        {
            let mut access_frequency = self.access_frequency.write().await;
            for (_, keys) in access_frequency.iter_mut() {
                keys.retain(|k| k != key);
            }
            access_frequency.retain(|_, keys| !keys.is_empty());
        }
    }

    /// 更新命中统计
    async fn update_stats_hit(&self) {
        let mut stats = self.stats.write().await;
        stats.hits += 1;
        stats.hit_rate = stats.hits as f64 / stats.total_requests as f64;
    }

    /// 更新未命中统计
    async fn update_stats_miss(&self) {
        let mut stats = self.stats.write().await;
        stats.misses += 1;
        stats.hit_rate = stats.hits as f64 / stats.total_requests as f64;
    }

    /// 更新平均访问时间
    async fn update_average_access_time(&self, access_time: f64) {
        let mut stats = self.stats.write().await;
        let total_requests = stats.total_requests as f64;
        stats.average_access_time = (stats.average_access_time * (total_requests - 1.0) + access_time) / total_requests;
    }

    /// 更新缓存统计
    async fn update_cache_stats(&self) {
        let cache = self.cache.read().await;
        let current_items = cache.len();
        let current_size = cache.values().map(|item| item.size).sum::<usize>();

        let mut stats = self.stats.write().await;
        stats.current_items = current_items;
        stats.current_size = current_size;
        stats.max_size = self.config.max_size;
        stats.utilization = current_size as f64 / self.config.max_size as f64;
    }

    /// 生成清理任务
    async fn spawn_cleanup_task(&self) -> Result<tokio::task::JoinHandle<()>> {
        let cache = Arc::clone(&self.cache);
        let access_order = Arc::clone(&self.access_order);
        let access_frequency = Arc::clone(&self.access_frequency);
        let stats = Arc::clone(&self.stats);
        let cleanup_interval = self.config.cleanup_interval;
        let is_running = Arc::clone(&self.is_running);

        let handle = tokio::spawn(async move {
            info!("缓存清理任务已启动");

            while *is_running.read().await {
                // 清理过期项
                let now = Instant::now();
                let expired_keys = {
                    let cache_guard = cache.read().await;
                    cache_guard.iter()
                        .filter(|(_, item)| {
                            if let Some(expires_at) = item.expires_at {
                                now > expires_at
                            } else {
                                false
                            }
                        })
                        .map(|(key, _)| key.clone())
                        .collect::<Vec<_>>()
                };

                if !expired_keys.is_empty() {
                    let mut cache_guard = cache.write().await;
                    let mut expired_count = 0;

                    for key in expired_keys {
                        if cache_guard.remove(&key).is_some() {
                            expired_count += 1;
                        }
                    }

                    if expired_count > 0 {
                        // 更新统计
                        {
                            let mut stats_guard = stats.write().await;
                            stats_guard.expirations += expired_count;
                        }

                        debug!("清理了 {} 个过期缓存项", expired_count);
                    }
                }

                // 清理访问跟踪中的无效项
                {
                    let cache_guard = cache.read().await;
                    let mut access_order_guard = access_order.write().await;
                    access_order_guard.retain(|_, key| cache_guard.contains_key(key));
                }

                {
                    let cache_guard = cache.read().await;
                    let mut access_frequency_guard = access_frequency.write().await;
                    for (_, keys) in access_frequency_guard.iter_mut() {
                        keys.retain(|key| cache_guard.contains_key(key));
                    }
                    access_frequency_guard.retain(|_, keys| !keys.is_empty());
                }

                // 等待下次清理
                tokio::time::sleep(cleanup_interval).await;
            }

            info!("缓存清理任务已停止");
        });

        Ok(handle)
    }

    /// 预热缓存
    pub async fn warmup<F, Fut>(&self, keys: Vec<K>, loader: F) -> Result<()>
    where
        F: Fn(K) -> Fut + Send + Sync,
        Fut: std::future::Future<Output = Result<V>> + Send,
    {
        info!("开始缓存预热，预热 {} 个项目", keys.len());

        let mut successful = 0;
        let mut failed = 0;

        for key in keys {
            match loader(key.clone()).await {
                Ok(value) => {
                    if let Err(e) = self.set(key, value, None, CachePriority::High).await {
                        error!("预热缓存项失败: {}", e);
                        failed += 1;
                    } else {
                        successful += 1;
                    }
                }
                Err(e) => {
                    error!("加载缓存项失败: {}", e);
                    failed += 1;
                }
            }
        }

        info!("缓存预热完成，成功: {}, 失败: {}", successful, failed);
        Ok(())
    }

    /// 检查缓存健康状态
    pub async fn health_check(&self) -> CacheHealthStatusEnum {
        let stats = self.get_stats().await;

        let mut issues = Vec::new();

        // 检查命中率
        if stats.hit_rate < 0.5 {
            issues.push("命中率过低".to_string());
        }

        // 检查利用率
        if stats.utilization > 0.9 {
            issues.push("缓存利用率过高".to_string());
        }

        // 检查平均访问时间
        if stats.average_access_time > 1000.0 { // 1ms
            issues.push("平均访问时间过长".to_string());
        }

        if issues.is_empty() {
            CacheHealthStatusEnum::Healthy
        } else {
            CacheHealthStatusEnum::Warning(issues)
        }
    }

    /// 获取缓存项详情
    pub async fn get_item_info(&self, key: &K) -> Option<CacheItemInfo> {
        let cache = self.cache.read().await;
        cache.get(key).map(|item| CacheItemInfo {
            created_at: item.created_at,
            last_accessed: item.last_accessed,
            access_count: item.access_count,
            expires_at: item.expires_at,
            size: item.size,
            priority: item.priority,
        })
    }
}

/// 缓存健康状态枚举
#[derive(Debug, Clone)]
pub enum CacheHealthStatusEnum {
    /// 健康
    Healthy,
    /// 警告
    Warning(Vec<String>),
    /// 错误
    Error(Vec<String>),
}

/// 缓存健康状态详情
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CacheHealthStatus {
    pub status: String,
    pub hit_rate: f64,
    pub utilization: f64,
    pub total_items: usize,
    pub expired_items: usize,
    pub memory_usage: usize,
    pub recommendations: Vec<String>,
}

/// 缓存项信息
#[derive(Debug, Clone)]
pub struct CacheItemInfo {
    pub created_at: Instant,
    pub last_accessed: Instant,
    pub access_count: u64,
    pub expires_at: Option<Instant>,
    pub size: usize,
    pub priority: CachePriority,
}
