use std::collections::HashMap;
use std::sync::{Arc, RwLock};
use std::time::{Duration, Instant};
use serde::{Deserialize, Serialize};
use tracing::{debug, info, warn};

/// 缓存管理器
/// 提供内存缓存功能，支持TTL和LRU淘汰策略
#[derive(Clone)]
pub struct CacheManager {
    cache: Arc<RwLock<CacheStorage>>,
    config: CacheConfig,
}

/// 缓存配置
#[derive(Debug, Clone)]
pub struct CacheConfig {
    /// 最大缓存条目数
    pub max_entries: usize,
    /// 默认TTL（秒）
    pub default_ttl_seconds: u64,
    /// 清理间隔（秒）
    pub cleanup_interval_seconds: u64,
    /// 启用统计
    pub enable_stats: bool,
}

/// 缓存存储
struct CacheStorage {
    entries: HashMap<String, CacheEntry>,
    access_order: Vec<String>, // LRU顺序
    stats: CacheStats,
}

/// 缓存条目
struct CacheEntry {
    data: Vec<u8>,
    created_at: Instant,
    expires_at: Option<Instant>,
    access_count: u64,
    last_accessed: Instant,
}

/// 缓存统计信息
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct CacheStats {
    pub total_requests: u64,
    pub cache_hits: u64,
    pub cache_misses: u64,
    pub evictions: u64,
    pub current_entries: usize,
    pub hit_rate: f64,
}

impl Default for CacheConfig {
    fn default() -> Self {
        Self {
            max_entries: 1000,
            default_ttl_seconds: 3600, // 1小时
            cleanup_interval_seconds: 300, // 5分钟
            enable_stats: true,
        }
    }
}

impl CacheManager {
    /// 创建新的缓存管理器
    pub fn new(config: Option<CacheConfig>) -> Self {
        let config = config.unwrap_or_default();
        let cache = Arc::new(RwLock::new(CacheStorage {
            entries: HashMap::new(),
            access_order: Vec::new(),
            stats: CacheStats::default(),
        }));

        let manager = Self { cache, config };

        // 启动清理任务
        manager.start_cleanup_task();

        info!("缓存管理器已启动，最大条目数: {}", manager.config.max_entries);
        manager
    }

    /// 存储数据到缓存
    pub fn put<T: Serialize>(&self, key: &str, value: &T, ttl_seconds: Option<u64>) -> Result<(), Box<dyn std::error::Error>> {
        let serialized = bincode::serialize(value)?;
        let ttl = ttl_seconds.unwrap_or(self.config.default_ttl_seconds);
        
        let mut storage = self.cache.write().unwrap();
        
        // 检查是否需要淘汰条目
        if storage.entries.len() >= self.config.max_entries {
            self.evict_lru(&mut storage);
        }

        let now = Instant::now();
        let expires_at = if ttl > 0 {
            Some(now + Duration::from_secs(ttl))
        } else {
            None
        };

        let entry = CacheEntry {
            data: serialized,
            created_at: now,
            expires_at,
            access_count: 0,
            last_accessed: now,
        };

        // 更新访问顺序
        if let Some(pos) = storage.access_order.iter().position(|k| k == key) {
            storage.access_order.remove(pos);
        }
        storage.access_order.push(key.to_string());

        storage.entries.insert(key.to_string(), entry);
        storage.stats.current_entries = storage.entries.len();

        debug!("缓存存储: key={}, ttl={}秒", key, ttl);
        Ok(())
    }

    /// 从缓存获取数据
    pub fn get<T: for<'de> Deserialize<'de>>(&self, key: &str) -> Option<T> {
        let mut storage = self.cache.write().unwrap();
        
        if self.config.enable_stats {
            storage.stats.total_requests += 1;
        }

        if let Some(entry) = storage.entries.get_mut(key) {
            let now = Instant::now();
            
            // 检查是否过期
            if let Some(expires_at) = entry.expires_at {
                if now > expires_at {
                    storage.entries.remove(key);
                    if let Some(pos) = storage.access_order.iter().position(|k| k == key) {
                        storage.access_order.remove(pos);
                    }
                    storage.stats.current_entries = storage.entries.len();
                    
                    if self.config.enable_stats {
                        storage.stats.cache_misses += 1;
                        storage.stats.hit_rate = storage.stats.cache_hits as f64 / storage.stats.total_requests as f64;
                    }
                    
                    debug!("缓存过期: key={}", key);
                    return None;
                }
            }

            // 更新访问信息
            entry.access_count += 1;
            entry.last_accessed = now;

            // 克隆数据以避免借用冲突
            let data = entry.data.clone();

            // 更新LRU顺序
            if let Some(pos) = storage.access_order.iter().position(|k| k == key) {
                storage.access_order.remove(pos);
            }
            storage.access_order.push(key.to_string());

            // 反序列化数据
            if let Ok(value) = bincode::deserialize::<T>(&data) {
                if self.config.enable_stats {
                    storage.stats.cache_hits += 1;
                    storage.stats.hit_rate = storage.stats.cache_hits as f64 / storage.stats.total_requests as f64;
                }
                
                debug!("缓存命中: key={}", key);
                Some(value)
            } else {
                warn!("缓存数据反序列化失败: key={}", key);
                None
            }
        } else {
            if self.config.enable_stats {
                storage.stats.cache_misses += 1;
                storage.stats.hit_rate = storage.stats.cache_hits as f64 / storage.stats.total_requests as f64;
            }
            
            debug!("缓存未命中: key={}", key);
            None
        }
    }

    /// 删除缓存条目
    pub fn remove(&self, key: &str) -> bool {
        let mut storage = self.cache.write().unwrap();
        
        if storage.entries.remove(key).is_some() {
            if let Some(pos) = storage.access_order.iter().position(|k| k == key) {
                storage.access_order.remove(pos);
            }
            storage.stats.current_entries = storage.entries.len();
            
            debug!("缓存删除: key={}", key);
            true
        } else {
            false
        }
    }

    /// 清空缓存
    pub fn clear(&self) {
        let mut storage = self.cache.write().unwrap();
        storage.entries.clear();
        storage.access_order.clear();
        storage.stats.current_entries = 0;
        
        info!("缓存已清空");
    }

    /// 检查缓存中是否存在指定键
    pub fn contains_key(&self, key: &str) -> bool {
        let storage = self.cache.read().unwrap();
        
        if let Some(entry) = storage.entries.get(key) {
            // 检查是否过期
            if let Some(expires_at) = entry.expires_at {
                Instant::now() <= expires_at
            } else {
                true
            }
        } else {
            false
        }
    }

    /// 获取缓存统计信息
    pub fn get_stats(&self) -> CacheStats {
        let storage = self.cache.read().unwrap();
        storage.stats.clone()
    }

    /// 清理过期条目
    pub fn cleanup_expired(&self) -> usize {
        let mut storage = self.cache.write().unwrap();
        let now = Instant::now();
        let mut expired_keys = Vec::new();

        for (key, entry) in &storage.entries {
            if let Some(expires_at) = entry.expires_at {
                if now > expires_at {
                    expired_keys.push(key.clone());
                }
            }
        }

        for key in &expired_keys {
            storage.entries.remove(key);
            if let Some(pos) = storage.access_order.iter().position(|k| k == key) {
                storage.access_order.remove(pos);
            }
        }

        storage.stats.current_entries = storage.entries.len();
        let expired_count = expired_keys.len();

        if expired_count > 0 {
            debug!("清理过期缓存条目: {} 个", expired_count);
        }

        expired_count
    }

    /// LRU淘汰
    fn evict_lru(&self, storage: &mut CacheStorage) {
        if let Some(lru_key) = storage.access_order.first().cloned() {
            storage.entries.remove(&lru_key);
            storage.access_order.remove(0);
            storage.stats.evictions += 1;
            storage.stats.current_entries = storage.entries.len();
            
            debug!("LRU淘汰缓存条目: key={}", lru_key);
        }
    }

    /// 启动清理任务
    fn start_cleanup_task(&self) {
        let cache = self.cache.clone();
        let interval = self.config.cleanup_interval_seconds;

        tokio::spawn(async move {
            let mut cleanup_interval = tokio::time::interval(Duration::from_secs(interval));
            
            loop {
                cleanup_interval.tick().await;
                
                let now = Instant::now();
                let mut expired_keys = Vec::new();

                // 收集过期键
                {
                    let storage = cache.read().unwrap();
                    for (key, entry) in &storage.entries {
                        if let Some(expires_at) = entry.expires_at {
                            if now > expires_at {
                                expired_keys.push(key.clone());
                            }
                        }
                    }
                }

                // 删除过期条目
                if !expired_keys.is_empty() {
                    let mut storage = cache.write().unwrap();
                    for key in &expired_keys {
                        storage.entries.remove(key);
                        if let Some(pos) = storage.access_order.iter().position(|k| k == key) {
                            storage.access_order.remove(pos);
                        }
                    }
                    storage.stats.current_entries = storage.entries.len();
                    
                    debug!("定期清理过期缓存条目: {} 个", expired_keys.len());
                }
            }
        });
    }
}

/// 工作流缓存键生成器
pub struct WorkflowCacheKeys;

impl WorkflowCacheKeys {
    /// 工作流模板缓存键
    pub fn template(template_id: i64) -> String {
        format!("template:{}", template_id)
    }

    /// 工作流模板列表缓存键
    pub fn template_list(filter_hash: &str) -> String {
        format!("template_list:{}", filter_hash)
    }

    /// 执行记录缓存键
    pub fn execution_record(record_id: i64) -> String {
        format!("execution_record:{}", record_id)
    }

    /// 执行历史缓存键
    pub fn execution_history(filter_hash: &str, page: u32, page_size: u32) -> String {
        format!("execution_history:{}:{}:{}", filter_hash, page, page_size)
    }

    /// 执行环境缓存键
    pub fn execution_environment(env_id: i64) -> String {
        format!("execution_environment:{}", env_id)
    }

    /// 可用环境列表缓存键
    pub fn available_environments(workflow_type: &str) -> String {
        format!("available_environments:{}", workflow_type)
    }

    /// 执行统计缓存键
    pub fn execution_statistics(filter_hash: &str) -> String {
        format!("execution_statistics:{}", filter_hash)
    }

    /// 系统健康状态缓存键
    pub fn system_health() -> String {
        "system_health".to_string()
    }

    /// 性能指标缓存键
    pub fn performance_metrics() -> String {
        "performance_metrics".to_string()
    }
}
