use super::error_types::{WorkflowError, ErrorContext, ErrorSeverity};
use anyhow::Result;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use tracing::{debug, info, warn, error, Level};

/// 错误日志记录器
pub struct ErrorLogger {
    log_storage: Arc<Mutex<Vec<ErrorLogEntry>>>,
    config: ErrorLoggingConfig,
}

/// 错误日志配置
#[derive(Debug, Clone)]
pub struct ErrorLoggingConfig {
    /// 最大日志条目数
    pub max_entries: usize,
    /// 日志级别
    pub log_level: ErrorSeverity,
    /// 是否记录堆栈跟踪
    pub include_stack_trace: bool,
    /// 是否记录上下文信息
    pub include_context: bool,
    /// 日志轮转间隔（小时）
    pub rotation_interval_hours: u64,
}

impl Default for ErrorLoggingConfig {
    fn default() -> Self {
        Self {
            max_entries: 10000,
            log_level: ErrorSeverity::Low,
            include_stack_trace: true,
            include_context: true,
            rotation_interval_hours: 24,
        }
    }
}

/// 错误日志条目
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ErrorLogEntry {
    pub id: String,
    pub error: WorkflowError,
    pub context: Option<ErrorContext>,
    pub stack_trace: Option<String>,
    pub logged_at: DateTime<Utc>,
    pub resolved_at: Option<DateTime<Utc>>,
    pub resolution_notes: Option<String>,
}

impl ErrorLogger {
    /// 创建新的错误日志记录器
    pub fn new(config: Option<ErrorLoggingConfig>) -> Self {
        Self {
            log_storage: Arc::new(Mutex::new(Vec::new())),
            config: config.unwrap_or_default(),
        }
    }

    /// 记录错误
    pub fn log_error(
        &self,
        error: WorkflowError,
        context: Option<ErrorContext>,
        stack_trace: Option<String>,
    ) -> String {
        let entry_id = format!("error_{}", chrono::Utc::now().timestamp_millis());
        
        // 检查是否应该记录此错误
        if !self.should_log_error(&error) {
            return entry_id;
        }

        let entry = ErrorLogEntry {
            id: entry_id.clone(),
            error: error.clone(),
            context: context.clone(),
            stack_trace: if self.config.include_stack_trace { stack_trace } else { None },
            logged_at: Utc::now(),
            resolved_at: None,
            resolution_notes: None,
        };

        // 存储到内存
        {
            let mut storage = self.log_storage.lock().unwrap();
            storage.push(entry.clone());
            
            // 检查是否需要清理旧条目
            if storage.len() > self.config.max_entries {
                storage.remove(0);
            }
        }

        // 记录到tracing日志
        self.log_to_tracing(&error, &context);

        info!("错误已记录，ID: {}", entry_id);
        entry_id
    }

    /// 检查是否应该记录错误
    fn should_log_error(&self, error: &WorkflowError) -> bool {
        let error_severity = error.severity();
        match (&self.config.log_level, &error_severity) {
            (ErrorSeverity::Critical, _) => matches!(error_severity, ErrorSeverity::Critical),
            (ErrorSeverity::High, _) => matches!(error_severity, ErrorSeverity::High | ErrorSeverity::Critical),
            (ErrorSeverity::Medium, _) => !matches!(error_severity, ErrorSeverity::Low),
            (ErrorSeverity::Low, _) => true,
        }
    }

    /// 记录到tracing日志系统
    fn log_to_tracing(&self, error: &WorkflowError, context: &Option<ErrorContext>) {
        let context_str = if let Some(ctx) = context {
            format!(" [用户: {:?}, 会话: {:?}, 操作: {:?}]", 
                   ctx.user_id, ctx.session_id, ctx.operation)
        } else {
            String::new()
        };

        match error.severity() {
            ErrorSeverity::Critical => {
                error!("严重错误: {}{}", error, context_str);
            }
            ErrorSeverity::High => {
                error!("高级错误: {}{}", error, context_str);
            }
            ErrorSeverity::Medium => {
                warn!("中级错误: {}{}", error, context_str);
            }
            ErrorSeverity::Low => {
                info!("低级错误: {}{}", error, context_str);
            }
        }
    }

    /// 标记错误为已解决
    pub fn mark_resolved(&self, entry_id: &str, resolution_notes: Option<String>) -> Result<()> {
        let mut storage = self.log_storage.lock().unwrap();
        
        if let Some(entry) = storage.iter_mut().find(|e| e.id == entry_id) {
            entry.resolved_at = Some(Utc::now());
            entry.resolution_notes = resolution_notes;
            info!("错误已标记为解决，ID: {}", entry_id);
            Ok(())
        } else {
            Err(anyhow::anyhow!("未找到错误日志条目: {}", entry_id))
        }
    }

    /// 获取错误日志条目
    pub fn get_error_log(&self, entry_id: &str) -> Option<ErrorLogEntry> {
        let storage = self.log_storage.lock().unwrap();
        storage.iter().find(|e| e.id == entry_id).cloned()
    }

    /// 获取所有错误日志
    pub fn get_all_error_logs(&self) -> Vec<ErrorLogEntry> {
        let storage = self.log_storage.lock().unwrap();
        storage.clone()
    }

    /// 获取未解决的错误
    pub fn get_unresolved_errors(&self) -> Vec<ErrorLogEntry> {
        let storage = self.log_storage.lock().unwrap();
        storage.iter()
            .filter(|entry| entry.resolved_at.is_none())
            .cloned()
            .collect()
    }

    /// 获取错误统计信息
    pub fn get_error_statistics(&self) -> ErrorStatistics {
        let storage = self.log_storage.lock().unwrap();
        let mut stats = ErrorStatistics::default();

        for entry in storage.iter() {
            stats.total_errors += 1;
            
            match entry.error.severity() {
                ErrorSeverity::Critical => stats.critical_errors += 1,
                ErrorSeverity::High => stats.high_errors += 1,
                ErrorSeverity::Medium => stats.medium_errors += 1,
                ErrorSeverity::Low => stats.low_errors += 1,
            }

            if entry.resolved_at.is_some() {
                stats.resolved_errors += 1;
            }

            // 按错误类型统计
            let error_type = match &entry.error {
                WorkflowError::Database(_) => "Database",
                WorkflowError::Execution(_) => "Execution",
                WorkflowError::Template(_) => "Template",
                WorkflowError::Environment(_) => "Environment",
                WorkflowError::Network(_) => "Network",
                WorkflowError::FileSystem(_) => "FileSystem",
                WorkflowError::Validation(_) => "Validation",
                WorkflowError::Permission(_) => "Permission",
                WorkflowError::Configuration(_) => "Configuration",
                WorkflowError::System(_) => "System",
            };
            
            *stats.errors_by_type.entry(error_type.to_string()).or_insert(0) += 1;
        }

        stats.resolution_rate = if stats.total_errors > 0 {
            stats.resolved_errors as f64 / stats.total_errors as f64
        } else {
            0.0
        };

        stats
    }

    /// 清理旧的错误日志
    pub fn cleanup_old_logs(&self, older_than_hours: u64) -> usize {
        let mut storage = self.log_storage.lock().unwrap();
        let cutoff_time = Utc::now() - chrono::Duration::hours(older_than_hours as i64);
        
        let initial_count = storage.len();
        storage.retain(|entry| entry.logged_at > cutoff_time);
        let removed_count = initial_count - storage.len();

        if removed_count > 0 {
            info!("清理了 {} 个旧的错误日志条目", removed_count);
        }

        removed_count
    }

    /// 导出错误日志
    pub fn export_logs(&self, format: ExportFormat) -> Result<String> {
        let storage = self.log_storage.lock().unwrap();
        
        match format {
            ExportFormat::Json => {
                let json = serde_json::to_string_pretty(&*storage)?;
                Ok(json)
            }
            ExportFormat::Csv => {
                let mut csv = String::from("ID,Error Type,Severity,Message,Logged At,Resolved At\n");
                
                for entry in storage.iter() {
                    let error_type = match &entry.error {
                        WorkflowError::Database(_) => "Database",
                        WorkflowError::Execution(_) => "Execution",
                        WorkflowError::Template(_) => "Template",
                        WorkflowError::Environment(_) => "Environment",
                        WorkflowError::Network(_) => "Network",
                        WorkflowError::FileSystem(_) => "FileSystem",
                        WorkflowError::Validation(_) => "Validation",
                        WorkflowError::Permission(_) => "Permission",
                        WorkflowError::Configuration(_) => "Configuration",
                        WorkflowError::System(_) => "System",
                    };
                    
                    let severity = format!("{:?}", entry.error.severity());
                    let message = entry.error.to_string().replace(",", ";");
                    let resolved_at = entry.resolved_at
                        .map(|dt| dt.to_rfc3339())
                        .unwrap_or_else(|| "未解决".to_string());
                    
                    csv.push_str(&format!("{},{},{},{},{},{}\n",
                        entry.id, error_type, severity, message,
                        entry.logged_at.to_rfc3339(), resolved_at));
                }
                
                Ok(csv)
            }
        }
    }
}

/// 错误统计信息
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct ErrorStatistics {
    pub total_errors: u32,
    pub critical_errors: u32,
    pub high_errors: u32,
    pub medium_errors: u32,
    pub low_errors: u32,
    pub resolved_errors: u32,
    pub resolution_rate: f64,
    pub errors_by_type: HashMap<String, u32>,
}

/// 导出格式
#[derive(Debug, Clone)]
pub enum ExportFormat {
    Json,
    Csv,
}

/// 错误趋势分析器
pub struct ErrorTrendAnalyzer;

impl ErrorTrendAnalyzer {
    /// 分析错误趋势
    pub fn analyze_trends(logs: &[ErrorLogEntry]) -> ErrorTrendAnalysis {
        let mut analysis = ErrorTrendAnalysis::default();
        
        if logs.is_empty() {
            return analysis;
        }

        // 按时间排序
        let mut sorted_logs = logs.to_vec();
        sorted_logs.sort_by(|a, b| a.logged_at.cmp(&b.logged_at));

        // 计算时间范围
        analysis.start_time = sorted_logs.first().unwrap().logged_at;
        analysis.end_time = sorted_logs.last().unwrap().logged_at;

        // 按小时分组统计
        let mut hourly_counts: HashMap<String, u32> = HashMap::new();
        for log in &sorted_logs {
            let hour_key = log.logged_at.format("%Y-%m-%d %H:00").to_string();
            *hourly_counts.entry(hour_key).or_insert(0) += 1;
        }

        // 计算趋势
        let counts: Vec<u32> = hourly_counts.values().cloned().collect();
        if counts.len() > 1 {
            let sum: u32 = counts.iter().sum();
            analysis.average_errors_per_hour = sum as f64 / counts.len() as f64;
            
            // 简单的趋势计算（最后几个小时vs前几个小时）
            let mid_point = counts.len() / 2;
            let first_half_avg: f64 = counts[..mid_point].iter().sum::<u32>() as f64 / mid_point as f64;
            let second_half_avg: f64 = counts[mid_point..].iter().sum::<u32>() as f64 / (counts.len() - mid_point) as f64;
            
            analysis.trend_direction = if second_half_avg > first_half_avg * 1.2 {
                TrendDirection::Increasing
            } else if second_half_avg < first_half_avg * 0.8 {
                TrendDirection::Decreasing
            } else {
                TrendDirection::Stable
            };
        }

        analysis
    }
}

/// 错误趋势分析结果
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct ErrorTrendAnalysis {
    pub start_time: DateTime<Utc>,
    pub end_time: DateTime<Utc>,
    pub average_errors_per_hour: f64,
    pub trend_direction: TrendDirection,
}

/// 趋势方向
#[derive(Debug, Default, Serialize, Deserialize)]
pub enum TrendDirection {
    #[default]
    Stable,
    Increasing,
    Decreasing,
}
