use std::collections::HashMap;
use std::sync::Arc;
use std::time::{Duration, Instant};
use tokio::sync::RwLock;
// use anyhow::Result; // 暂时不需要
use serde::{Serialize, Deserialize};

use crate::data::models::template::Template;

/// 缓存项
#[derive(Debug, Clone)]
struct CacheItem<T> {
    data: T,
    created_at: Instant,
    last_accessed: Instant,
    access_count: u64,
}

impl<T> CacheItem<T> {
    fn new(data: T) -> Self {
        let now = Instant::now();
        Self {
            data,
            created_at: now,
            last_accessed: now,
            access_count: 1,
        }
    }

    fn access(&mut self) -> &T {
        self.last_accessed = Instant::now();
        self.access_count += 1;
        &self.data
    }

    fn is_expired(&self, ttl: Duration) -> bool {
        self.created_at.elapsed() > ttl
    }
}

/// 缓存配置
#[derive(Debug, Clone)]
pub struct CacheConfig {
    /// 最大缓存项数量
    pub max_items: usize,
    /// 生存时间
    pub ttl: Duration,
    /// 清理间隔
    pub cleanup_interval: Duration,
    /// 启用LRU淘汰
    pub enable_lru: bool,
}

impl Default for CacheConfig {
    fn default() -> Self {
        Self {
            max_items: 1000,
            ttl: Duration::from_secs(3600), // 1小时
            cleanup_interval: Duration::from_secs(300), // 5分钟
            enable_lru: true,
        }
    }
}

/// 缓存统计
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CacheStats {
    pub total_items: usize,
    pub hit_count: u64,
    pub miss_count: u64,
    pub hit_rate: f64,
    pub eviction_count: u64,
    pub memory_usage_bytes: usize,
}

/// 模板缓存服务
/// 提供高性能的模板数据缓存，支持LRU淘汰和TTL过期
pub struct TemplateCacheService {
    cache: Arc<RwLock<HashMap<String, CacheItem<Template>>>>,
    config: CacheConfig,
    stats: Arc<RwLock<CacheStats>>,
    last_cleanup: Arc<RwLock<Instant>>,
}

impl TemplateCacheService {
    pub fn new() -> Self {
        Self::with_config(CacheConfig::default())
    }

    pub fn with_config(config: CacheConfig) -> Self {
        Self {
            cache: Arc::new(RwLock::new(HashMap::new())),
            config,
            stats: Arc::new(RwLock::new(CacheStats {
                total_items: 0,
                hit_count: 0,
                miss_count: 0,
                hit_rate: 0.0,
                eviction_count: 0,
                memory_usage_bytes: 0,
            })),
            last_cleanup: Arc::new(RwLock::new(Instant::now())),
        }
    }

    /// 获取模板（如果缓存中存在）
    pub async fn get(&self, template_id: &str) -> Option<Template> {
        // 检查是否需要清理
        self.maybe_cleanup().await;

        let mut cache = self.cache.write().await;
        let mut stats = self.stats.write().await;

        if let Some(item) = cache.get_mut(template_id) {
            if item.is_expired(self.config.ttl) {
                // 过期项，移除
                cache.remove(template_id);
                stats.miss_count += 1;
                None
            } else {
                // 命中缓存
                let template = item.access().clone();
                stats.hit_count += 1;
                self.update_hit_rate(&mut stats);
                Some(template)
            }
        } else {
            // 缓存未命中
            stats.miss_count += 1;
            self.update_hit_rate(&mut stats);
            None
        }
    }

    /// 存储模板到缓存
    pub async fn put(&self, template_id: String, template: Template) {
        let mut cache = self.cache.write().await;
        let mut stats = self.stats.write().await;

        // 检查是否需要淘汰
        if cache.len() >= self.config.max_items {
            self.evict_items(&mut cache, &mut stats).await;
        }

        // 添加新项
        cache.insert(template_id, CacheItem::new(template));
        stats.total_items = cache.len();
        self.update_memory_usage(&mut stats, &cache);
    }

    /// 移除缓存项
    pub async fn remove(&self, template_id: &str) -> bool {
        let mut cache = self.cache.write().await;
        let mut stats = self.stats.write().await;

        let removed = cache.remove(template_id).is_some();
        if removed {
            stats.total_items = cache.len();
            self.update_memory_usage(&mut stats, &cache);
        }
        removed
    }

    /// 清空缓存
    pub async fn clear(&self) {
        let mut cache = self.cache.write().await;
        let mut stats = self.stats.write().await;

        cache.clear();
        stats.total_items = 0;
        stats.memory_usage_bytes = 0;
    }

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

    /// 预热缓存
    pub async fn warm_up(&self, templates: Vec<Template>) {
        for template in templates {
            self.put(template.id.clone(), template).await;
        }
    }

    /// 批量获取模板
    pub async fn get_batch(&self, template_ids: &[String]) -> HashMap<String, Template> {
        let mut result = HashMap::new();
        
        for id in template_ids {
            if let Some(template) = self.get(id).await {
                result.insert(id.clone(), template);
            }
        }
        
        result
    }

    /// 批量存储模板
    pub async fn put_batch(&self, templates: HashMap<String, Template>) {
        for (id, template) in templates {
            self.put(id, template).await;
        }
    }

    /// 检查是否需要清理过期项
    async fn maybe_cleanup(&self) {
        let last_cleanup = *self.last_cleanup.read().await;
        if last_cleanup.elapsed() >= self.config.cleanup_interval {
            self.cleanup_expired().await;
        }
    }

    /// 清理过期项
    async fn cleanup_expired(&self) {
        let mut cache = self.cache.write().await;
        let mut stats = self.stats.write().await;
        let mut last_cleanup = self.last_cleanup.write().await;

        let initial_count = cache.len();
        cache.retain(|_, item| !item.is_expired(self.config.ttl));
        let removed_count = initial_count - cache.len();

        stats.total_items = cache.len();
        stats.eviction_count += removed_count as u64;
        self.update_memory_usage(&mut stats, &cache);
        *last_cleanup = Instant::now();
    }

    /// 淘汰缓存项（LRU策略）
    async fn evict_items(
        &self,
        cache: &mut HashMap<String, CacheItem<Template>>,
        stats: &mut CacheStats,
    ) {
        if !self.config.enable_lru {
            return;
        }

        let evict_count = cache.len() / 4; // 淘汰25%的项

        // 按最后访问时间排序，移除最久未访问的项
        let mut items: Vec<_> = cache.iter().map(|(k, v)| (k.clone(), v.last_accessed)).collect();
        items.sort_by_key(|(_, last_accessed)| *last_accessed);

        let keys_to_remove: Vec<String> = items.iter().take(evict_count).map(|(k, _)| k.clone()).collect();
        for key in keys_to_remove {
            cache.remove(&key);
        }

        stats.eviction_count += evict_count as u64;
    }

    /// 更新命中率
    fn update_hit_rate(&self, stats: &mut CacheStats) {
        let total = stats.hit_count + stats.miss_count;
        if total > 0 {
            stats.hit_rate = stats.hit_count as f64 / total as f64;
        }
    }

    /// 更新内存使用量估算
    fn update_memory_usage(
        &self,
        stats: &mut CacheStats,
        cache: &HashMap<String, CacheItem<Template>>,
    ) {
        // 简单估算：每个模板约1KB + 键的大小
        let estimated_size = cache.iter()
            .map(|(key, _)| key.len() + 1024) // 1KB per template estimate
            .sum();
        stats.memory_usage_bytes = estimated_size;
    }
}

/// 缓存管理器
/// 提供全局的缓存管理功能
pub struct CacheManager {
    template_cache: Arc<TemplateCacheService>,
}

impl CacheManager {
    pub fn new() -> Self {
        Self {
            template_cache: Arc::new(TemplateCacheService::new()),
        }
    }

    pub fn template_cache(&self) -> Arc<TemplateCacheService> {
        self.template_cache.clone()
    }

    /// 获取所有缓存的统计信息
    pub async fn get_all_stats(&self) -> HashMap<String, CacheStats> {
        let mut stats = HashMap::new();
        stats.insert("templates".to_string(), self.template_cache.get_stats().await);
        stats
    }

    /// 清空所有缓存
    pub async fn clear_all(&self) {
        self.template_cache.clear().await;
    }

    /// 获取总内存使用量
    pub async fn get_total_memory_usage(&self) -> usize {
        self.template_cache.get_stats().await.memory_usage_bytes
    }
}

impl Default for CacheManager {
    fn default() -> Self {
        Self::new()
    }
}
