use super::error_types::{WorkflowError, ErrorContext, ErrorSeverity};
use super::error_logging::{ErrorLogEntry, ErrorStatistics};
use anyhow::Result;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use tracing::{info, warn, error};

/// 错误报告生成器
pub struct ErrorReportGenerator;

impl ErrorReportGenerator {
    /// 生成错误摘要报告
    pub fn generate_summary_report(
        logs: &[ErrorLogEntry],
        time_range: Option<(DateTime<Utc>, DateTime<Utc>)>,
    ) -> ErrorSummaryReport {
        let filtered_logs = if let Some((start, end)) = time_range {
            logs.iter()
                .filter(|log| log.logged_at >= start && log.logged_at <= end)
                .cloned()
                .collect::<Vec<_>>()
        } else {
            logs.to_vec()
        };

        let mut report = ErrorSummaryReport {
            report_id: format!("report_{}", chrono::Utc::now().timestamp_millis()),
            generated_at: Utc::now(),
            time_range_start: time_range.map(|(start, _)| start),
            time_range_end: time_range.map(|(_, end)| end),
            total_errors: filtered_logs.len() as u32,
            ..Default::default()
        };

        // 按严重程度统计
        for log in &filtered_logs {
            match log.error.severity() {
                ErrorSeverity::Critical => report.critical_errors += 1,
                ErrorSeverity::High => report.high_errors += 1,
                ErrorSeverity::Medium => report.medium_errors += 1,
                ErrorSeverity::Low => report.low_errors += 1,
            }

            if log.resolved_at.is_some() {
                report.resolved_errors += 1;
            }
        }

        // 计算解决率
        report.resolution_rate = if report.total_errors > 0 {
            report.resolved_errors as f64 / report.total_errors as f64
        } else {
            0.0
        };

        // 按错误类型统计
        for log in &filtered_logs {
            let error_type = Self::get_error_type_name(&log.error);
            *report.errors_by_type.entry(error_type).or_insert(0) += 1;
        }

        // 找出最常见的错误
        report.top_error_types = report.errors_by_type
            .iter()
            .map(|(k, v)| (k.clone(), *v))
            .collect::<Vec<_>>();
        report.top_error_types.sort_by(|a, b| b.1.cmp(&a.1));
        report.top_error_types.truncate(5);

        // 生成建议
        report.recommendations = Self::generate_recommendations(&filtered_logs);

        report
    }

    /// 生成详细错误报告
    pub fn generate_detailed_report(
        logs: &[ErrorLogEntry],
        include_resolved: bool,
    ) -> DetailedErrorReport {
        let filtered_logs = if include_resolved {
            logs.to_vec()
        } else {
            logs.iter()
                .filter(|log| log.resolved_at.is_none())
                .cloned()
                .collect()
        };

        let mut report = DetailedErrorReport {
            report_id: format!("detailed_report_{}", chrono::Utc::now().timestamp_millis()),
            generated_at: Utc::now(),
            include_resolved,
            total_entries: filtered_logs.len() as u32,
            entries: filtered_logs,
        };

        report
    }

    /// 生成性能影响报告
    pub fn generate_performance_impact_report(logs: &[ErrorLogEntry]) -> PerformanceImpactReport {
        let mut report = PerformanceImpactReport {
            report_id: format!("perf_report_{}", chrono::Utc::now().timestamp_millis()),
            generated_at: Utc::now(),
            ..Default::default()
        };

        // 分析执行错误对性能的影响
        let execution_errors: Vec<_> = logs.iter()
            .filter(|log| matches!(log.error, WorkflowError::Execution(_)))
            .collect();

        report.execution_failures = execution_errors.len() as u32;

        // 分析数据库错误对性能的影响
        let database_errors: Vec<_> = logs.iter()
            .filter(|log| matches!(log.error, WorkflowError::Database(_)))
            .collect();

        report.database_issues = database_errors.len() as u32;

        // 分析网络错误对性能的影响
        let network_errors: Vec<_> = logs.iter()
            .filter(|log| matches!(log.error, WorkflowError::Network(_)))
            .collect();

        report.network_issues = network_errors.len() as u32;

        // 估算性能影响
        report.estimated_downtime_minutes = Self::estimate_downtime(&logs);
        report.affected_operations = Self::count_affected_operations(&logs);

        // 生成性能优化建议
        report.optimization_suggestions = Self::generate_performance_suggestions(&logs);

        report
    }

    /// 获取错误类型名称
    fn get_error_type_name(error: &WorkflowError) -> String {
        match error {
            WorkflowError::Database(_) => "数据库错误".to_string(),
            WorkflowError::Execution(_) => "执行错误".to_string(),
            WorkflowError::Template(_) => "模板错误".to_string(),
            WorkflowError::Environment(_) => "环境错误".to_string(),
            WorkflowError::Network(_) => "网络错误".to_string(),
            WorkflowError::FileSystem(_) => "文件系统错误".to_string(),
            WorkflowError::Validation(_) => "验证错误".to_string(),
            WorkflowError::Permission(_) => "权限错误".to_string(),
            WorkflowError::Configuration(_) => "配置错误".to_string(),
            WorkflowError::System(_) => "系统错误".to_string(),
        }
    }

    /// 生成建议
    fn generate_recommendations(logs: &[ErrorLogEntry]) -> Vec<String> {
        let mut recommendations = Vec::new();

        // 分析错误模式
        let error_counts = Self::count_error_types(logs);

        // 数据库错误建议
        if let Some(&count) = error_counts.get("数据库错误") {
            if count > 10 {
                recommendations.push("数据库错误频发，建议检查数据库连接池配置和查询优化".to_string());
            }
        }

        // 执行错误建议
        if let Some(&count) = error_counts.get("执行错误") {
            if count > 5 {
                recommendations.push("工作流执行错误较多，建议检查执行环境状态和资源配置".to_string());
            }
        }

        // 网络错误建议
        if let Some(&count) = error_counts.get("网络错误") {
            if count > 3 {
                recommendations.push("网络错误频发，建议检查网络连接稳定性和超时配置".to_string());
            }
        }

        // 环境错误建议
        if let Some(&count) = error_counts.get("环境错误") {
            if count > 2 {
                recommendations.push("执行环境错误较多，建议进行环境健康检查和维护".to_string());
            }
        }

        // 通用建议
        if logs.len() > 50 {
            recommendations.push("错误总数较多，建议实施预防性监控和告警机制".to_string());
        }

        let unresolved_count = logs.iter().filter(|log| log.resolved_at.is_none()).count();
        if unresolved_count > 10 {
            recommendations.push("未解决错误较多，建议优先处理高优先级错误".to_string());
        }

        recommendations
    }

    /// 统计错误类型
    fn count_error_types(logs: &[ErrorLogEntry]) -> HashMap<String, u32> {
        let mut counts = HashMap::new();
        for log in logs {
            let error_type = Self::get_error_type_name(&log.error);
            *counts.entry(error_type).or_insert(0) += 1;
        }
        counts
    }

    /// 估算停机时间
    fn estimate_downtime(logs: &[ErrorLogEntry]) -> f64 {
        let critical_errors = logs.iter()
            .filter(|log| matches!(log.error.severity(), ErrorSeverity::Critical))
            .count();

        let high_errors = logs.iter()
            .filter(|log| matches!(log.error.severity(), ErrorSeverity::High))
            .count();

        // 简化的停机时间估算：严重错误每个5分钟，高级错误每个1分钟
        (critical_errors * 5 + high_errors * 1) as f64
    }

    /// 统计受影响的操作
    fn count_affected_operations(logs: &[ErrorLogEntry]) -> u32 {
        logs.iter()
            .filter_map(|log| log.context.as_ref())
            .filter_map(|ctx| ctx.operation.as_ref())
            .collect::<std::collections::HashSet<_>>()
            .len() as u32
    }

    /// 生成性能优化建议
    fn generate_performance_suggestions(logs: &[ErrorLogEntry]) -> Vec<String> {
        let mut suggestions = Vec::new();

        let database_errors = logs.iter()
            .filter(|log| matches!(log.error, WorkflowError::Database(_)))
            .count();

        if database_errors > 5 {
            suggestions.push("优化数据库查询性能，添加必要的索引".to_string());
            suggestions.push("考虑增加数据库连接池大小".to_string());
        }

        let execution_errors = logs.iter()
            .filter(|log| matches!(log.error, WorkflowError::Execution(_)))
            .count();

        if execution_errors > 3 {
            suggestions.push("优化工作流执行逻辑，减少资源消耗".to_string());
            suggestions.push("考虑增加执行环境的资源配置".to_string());
        }

        let network_errors = logs.iter()
            .filter(|log| matches!(log.error, WorkflowError::Network(_)))
            .count();

        if network_errors > 2 {
            suggestions.push("优化网络请求重试机制".to_string());
            suggestions.push("考虑使用CDN或缓存减少网络请求".to_string());
        }

        suggestions
    }
}

/// 错误摘要报告
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct ErrorSummaryReport {
    pub report_id: String,
    pub generated_at: DateTime<Utc>,
    pub time_range_start: Option<DateTime<Utc>>,
    pub time_range_end: Option<DateTime<Utc>>,
    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>,
    pub top_error_types: Vec<(String, u32)>,
    pub recommendations: Vec<String>,
}

/// 详细错误报告
#[derive(Debug, Serialize, Deserialize)]
pub struct DetailedErrorReport {
    pub report_id: String,
    pub generated_at: DateTime<Utc>,
    pub include_resolved: bool,
    pub total_entries: u32,
    pub entries: Vec<ErrorLogEntry>,
}

/// 性能影响报告
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct PerformanceImpactReport {
    pub report_id: String,
    pub generated_at: DateTime<Utc>,
    pub execution_failures: u32,
    pub database_issues: u32,
    pub network_issues: u32,
    pub estimated_downtime_minutes: f64,
    pub affected_operations: u32,
    pub optimization_suggestions: Vec<String>,
}

/// 错误报告导出器
pub struct ErrorReportExporter;

impl ErrorReportExporter {
    /// 导出摘要报告为HTML
    pub fn export_summary_to_html(report: &ErrorSummaryReport) -> String {
        format!(
            r#"
<!DOCTYPE html>
<html>
<head>
    <title>错误摘要报告</title>
    <style>
        body {{ font-family: Arial, sans-serif; margin: 20px; }}
        .header {{ background-color: #f0f0f0; padding: 10px; border-radius: 5px; }}
        .section {{ margin: 20px 0; }}
        .error-stats {{ display: flex; gap: 20px; }}
        .stat-box {{ border: 1px solid #ddd; padding: 10px; border-radius: 5px; }}
        .critical {{ border-color: #ff0000; }}
        .high {{ border-color: #ff8800; }}
        .medium {{ border-color: #ffaa00; }}
        .low {{ border-color: #00aa00; }}
    </style>
</head>
<body>
    <div class="header">
        <h1>错误摘要报告</h1>
        <p>报告ID: {}</p>
        <p>生成时间: {}</p>
    </div>
    
    <div class="section">
        <h2>错误统计</h2>
        <div class="error-stats">
            <div class="stat-box critical">
                <h3>严重错误</h3>
                <p>{}</p>
            </div>
            <div class="stat-box high">
                <h3>高级错误</h3>
                <p>{}</p>
            </div>
            <div class="stat-box medium">
                <h3>中级错误</h3>
                <p>{}</p>
            </div>
            <div class="stat-box low">
                <h3>低级错误</h3>
                <p>{}</p>
            </div>
        </div>
        <p>总错误数: {}</p>
        <p>已解决错误: {}</p>
        <p>解决率: {:.1}%</p>
    </div>
    
    <div class="section">
        <h2>主要错误类型</h2>
        <ul>
        {}
        </ul>
    </div>
    
    <div class="section">
        <h2>建议</h2>
        <ul>
        {}
        </ul>
    </div>
</body>
</html>
            "#,
            report.report_id,
            report.generated_at.format("%Y-%m-%d %H:%M:%S UTC"),
            report.critical_errors,
            report.high_errors,
            report.medium_errors,
            report.low_errors,
            report.total_errors,
            report.resolved_errors,
            report.resolution_rate * 100.0,
            report.top_error_types.iter()
                .map(|(name, count)| format!("<li>{}: {} 次</li>", name, count))
                .collect::<Vec<_>>()
                .join("\n"),
            report.recommendations.iter()
                .map(|rec| format!("<li>{}</li>", rec))
                .collect::<Vec<_>>()
                .join("\n")
        )
    }

    /// 导出报告为JSON
    pub fn export_to_json<T: Serialize>(report: &T) -> Result<String> {
        serde_json::to_string_pretty(report)
            .map_err(|e| anyhow::anyhow!("JSON序列化失败: {}", e))
    }
}
