use std::collections::HashMap;
use std::sync::Arc;
use std::time::{Duration, Instant};
use tokio::sync::RwLock;
use serde::{Serialize, Deserialize};

/// 性能指标类型
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum MetricType {
    /// 操作耗时（毫秒）
    Duration,
    /// 计数器
    Counter,
    /// 内存使用量（字节）
    Memory,
    /// 吞吐量（每秒操作数）
    Throughput,
    /// 错误率（百分比）
    ErrorRate,
}

/// 性能指标
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceMetric {
    pub name: String,
    pub metric_type: MetricType,
    pub value: f64,
    pub timestamp: u64,
    pub tags: HashMap<String, String>,
}

/// 性能统计
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceStats {
    pub metric_name: String,
    pub count: u64,
    pub sum: f64,
    pub min: f64,
    pub max: f64,
    pub avg: f64,
    pub p50: f64,
    pub p95: f64,
    pub p99: f64,
}

/// 操作计时器
pub struct Timer {
    name: String,
    start_time: Instant,
    tags: HashMap<String, String>,
}

impl Timer {
    pub fn new(name: String) -> Self {
        Self {
            name,
            start_time: Instant::now(),
            tags: HashMap::new(),
        }
    }

    pub fn with_tags(mut self, tags: HashMap<String, String>) -> Self {
        self.tags = tags;
        self
    }

    pub fn add_tag(mut self, key: String, value: String) -> Self {
        self.tags.insert(key, value);
        self
    }

    pub fn finish(self, monitor: &PerformanceMonitor) {
        let duration = self.start_time.elapsed().as_millis() as f64;
        monitor.record_metric(PerformanceMetric {
            name: self.name,
            metric_type: MetricType::Duration,
            value: duration,
            timestamp: chrono::Utc::now().timestamp() as u64,
            tags: self.tags,
        });
    }
}

/// 性能监控服务
/// 收集和分析应用性能指标
pub struct PerformanceMonitor {
    metrics: Arc<RwLock<Vec<PerformanceMetric>>>,
    stats_cache: Arc<RwLock<HashMap<String, PerformanceStats>>>,
    max_metrics: usize,
}

impl PerformanceMonitor {
    pub fn new() -> Self {
        Self {
            metrics: Arc::new(RwLock::new(Vec::new())),
            stats_cache: Arc::new(RwLock::new(HashMap::new())),
            max_metrics: 10000, // 最多保留10000个指标
        }
    }

    /// 记录性能指标
    pub fn record_metric(&self, metric: PerformanceMetric) {
        let monitor = self.clone();
        tokio::spawn(async move {
            let mut metrics = monitor.metrics.write().await;
            
            // 如果超过最大数量，移除最旧的指标
            if metrics.len() >= monitor.max_metrics {
                let drain_count = metrics.len() / 2;
                metrics.drain(0..drain_count); // 移除一半
            }
            
            metrics.push(metric.clone());
            
            // 更新统计缓存
            monitor.update_stats_cache(&metric).await;
        });
    }

    /// 开始计时
    pub fn start_timer(&self, name: &str) -> Timer {
        Timer::new(name.to_string())
    }

    /// 记录计数器
    pub fn increment_counter(&self, name: &str, value: f64) {
        self.record_metric(PerformanceMetric {
            name: name.to_string(),
            metric_type: MetricType::Counter,
            value,
            timestamp: chrono::Utc::now().timestamp() as u64,
            tags: HashMap::new(),
        });
    }

    /// 记录内存使用量
    pub fn record_memory_usage(&self, name: &str, bytes: u64) {
        self.record_metric(PerformanceMetric {
            name: name.to_string(),
            metric_type: MetricType::Memory,
            value: bytes as f64,
            timestamp: chrono::Utc::now().timestamp() as u64,
            tags: HashMap::new(),
        });
    }

    /// 记录吞吐量
    pub fn record_throughput(&self, name: &str, ops_per_second: f64) {
        self.record_metric(PerformanceMetric {
            name: name.to_string(),
            metric_type: MetricType::Throughput,
            value: ops_per_second,
            timestamp: chrono::Utc::now().timestamp() as u64,
            tags: HashMap::new(),
        });
    }

    /// 记录错误率
    pub fn record_error_rate(&self, name: &str, error_percentage: f64) {
        self.record_metric(PerformanceMetric {
            name: name.to_string(),
            metric_type: MetricType::ErrorRate,
            value: error_percentage,
            timestamp: chrono::Utc::now().timestamp() as u64,
            tags: HashMap::new(),
        });
    }

    /// 获取指定时间范围内的指标
    pub async fn get_metrics(&self, 
        name_filter: Option<&str>, 
        start_time: Option<u64>, 
        end_time: Option<u64>
    ) -> Vec<PerformanceMetric> {
        let metrics = self.metrics.read().await;
        
        metrics.iter()
            .filter(|m| {
                // 名称过滤
                if let Some(name) = name_filter {
                    if !m.name.contains(name) {
                        return false;
                    }
                }
                
                // 时间范围过滤
                if let Some(start) = start_time {
                    if m.timestamp < start {
                        return false;
                    }
                }
                
                if let Some(end) = end_time {
                    if m.timestamp > end {
                        return false;
                    }
                }
                
                true
            })
            .cloned()
            .collect()
    }

    /// 获取性能统计
    pub async fn get_stats(&self, metric_name: &str) -> Option<PerformanceStats> {
        // 先检查缓存
        {
            let cache = self.stats_cache.read().await;
            if let Some(stats) = cache.get(metric_name) {
                return Some(stats.clone());
            }
        }
        
        // 计算统计
        let metrics = self.get_metrics(Some(metric_name), None, None).await;
        if metrics.is_empty() {
            return None;
        }
        
        let values: Vec<f64> = metrics.iter().map(|m| m.value).collect();
        let stats = self.calculate_stats(metric_name, &values);
        
        // 更新缓存
        {
            let mut cache = self.stats_cache.write().await;
            cache.insert(metric_name.to_string(), stats.clone());
        }
        
        Some(stats)
    }

    /// 获取所有指标的统计
    pub async fn get_all_stats(&self) -> HashMap<String, PerformanceStats> {
        let metrics = self.metrics.read().await;
        let mut metric_groups: HashMap<String, Vec<f64>> = HashMap::new();
        
        // 按名称分组
        for metric in metrics.iter() {
            metric_groups.entry(metric.name.clone())
                .or_insert_with(Vec::new)
                .push(metric.value);
        }
        
        // 计算每组的统计
        let mut all_stats = HashMap::new();
        for (name, values) in metric_groups {
            if !values.is_empty() {
                let stats = self.calculate_stats(&name, &values);
                all_stats.insert(name, stats);
            }
        }
        
        all_stats
    }

    /// 清理旧指标
    pub async fn cleanup_old_metrics(&self, older_than: Duration) {
        let cutoff_time = (chrono::Utc::now().timestamp() as u64)
            .saturating_sub(older_than.as_secs());
        
        let mut metrics = self.metrics.write().await;
        metrics.retain(|m| m.timestamp >= cutoff_time);
        
        // 清理统计缓存
        let mut cache = self.stats_cache.write().await;
        cache.clear();
    }

    /// 获取系统性能概览
    pub async fn get_performance_overview(&self) -> HashMap<String, serde_json::Value> {
        let mut overview = HashMap::new();
        
        // 模板导入性能
        if let Some(import_stats) = self.get_stats("template_import_duration").await {
            overview.insert("template_import".to_string(), serde_json::json!({
                "avg_duration_ms": import_stats.avg,
                "p95_duration_ms": import_stats.p95,
                "total_imports": import_stats.count
            }));
        }
        
        // 文件上传性能
        if let Some(upload_stats) = self.get_stats("file_upload_duration").await {
            overview.insert("file_upload".to_string(), serde_json::json!({
                "avg_duration_ms": upload_stats.avg,
                "p95_duration_ms": upload_stats.p95,
                "total_uploads": upload_stats.count
            }));
        }
        
        // 数据库查询性能
        if let Some(db_stats) = self.get_stats("database_query_duration").await {
            overview.insert("database".to_string(), serde_json::json!({
                "avg_query_ms": db_stats.avg,
                "p95_query_ms": db_stats.p95,
                "total_queries": db_stats.count
            }));
        }
        
        // 内存使用情况
        if let Some(memory_stats) = self.get_stats("memory_usage").await {
            overview.insert("memory".to_string(), serde_json::json!({
                "avg_usage_mb": memory_stats.avg / 1024.0 / 1024.0,
                "max_usage_mb": memory_stats.max / 1024.0 / 1024.0,
                "current_usage_mb": memory_stats.avg / 1024.0 / 1024.0
            }));
        }
        
        overview
    }

    /// 更新统计缓存
    async fn update_stats_cache(&self, metric: &PerformanceMetric) {
        // 简单的缓存失效策略：清除相关的缓存项
        let mut cache = self.stats_cache.write().await;
        cache.remove(&metric.name);
    }

    /// 计算统计数据
    fn calculate_stats(&self, name: &str, values: &[f64]) -> PerformanceStats {
        if values.is_empty() {
            return PerformanceStats {
                metric_name: name.to_string(),
                count: 0,
                sum: 0.0,
                min: 0.0,
                max: 0.0,
                avg: 0.0,
                p50: 0.0,
                p95: 0.0,
                p99: 0.0,
            };
        }

        let mut sorted_values = values.to_vec();
        sorted_values.sort_by(|a, b| a.partial_cmp(b).unwrap());

        let count = values.len() as u64;
        let sum: f64 = values.iter().sum();
        let min = sorted_values[0];
        let max = sorted_values[sorted_values.len() - 1];
        let avg = sum / values.len() as f64;

        let p50 = self.percentile(&sorted_values, 0.5);
        let p95 = self.percentile(&sorted_values, 0.95);
        let p99 = self.percentile(&sorted_values, 0.99);

        PerformanceStats {
            metric_name: name.to_string(),
            count,
            sum,
            min,
            max,
            avg,
            p50,
            p95,
            p99,
        }
    }

    /// 计算百分位数
    fn percentile(&self, sorted_values: &[f64], percentile: f64) -> f64 {
        if sorted_values.is_empty() {
            return 0.0;
        }

        let index = (percentile * (sorted_values.len() - 1) as f64).round() as usize;
        sorted_values[index.min(sorted_values.len() - 1)]
    }
}

impl Clone for PerformanceMonitor {
    fn clone(&self) -> Self {
        Self {
            metrics: self.metrics.clone(),
            stats_cache: self.stats_cache.clone(),
            max_metrics: self.max_metrics,
        }
    }
}

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