//! HTML Load Test Report Generator
//!
//! Generates comprehensive HTML reports with charts and statistics.

use anyhow::Result;
use serde_json::json;
use std::fs;
use std::path::Path;

use super::load_generator::LoadTestResults;
use super::metrics_collector::MetricsSummary;

/// Report generator for load test results
pub struct ReportGenerator;

impl ReportGenerator {
    /// Generate HTML report
    pub fn generate_html_report(
        output_path: &Path,
        results: &LoadTestResults,
        metrics_summary: &MetricsSummary,
    ) -> Result<()> {
        let html = Self::build_html_report(results, metrics_summary);
        fs::write(output_path, html)?;
        Ok(())
    }

    /// Generate JSON report
    pub fn generate_json_report(
        output_path: &Path,
        results: &LoadTestResults,
        metrics_summary: &MetricsSummary,
    ) -> Result<()> {
        let report = json!({
            "results": {
                "total_operations": results.total_operations,
                "successful_operations": results.successful_operations,
                "failed_operations": results.failed_operations,
                "total_duration_secs": results.total_duration.as_secs_f64(),
                "actual_rps": results.actual_rps,
                "latencies": {
                    "min_ms": results.latencies.min.as_secs_f64() * 1000.0,
                    "max_ms": results.latencies.max.as_secs_f64() * 1000.0,
                    "mean_ms": results.latencies.mean.as_secs_f64() * 1000.0,
                    "p50_ms": results.latencies.p50.as_secs_f64() * 1000.0,
                    "p95_ms": results.latencies.p95.as_secs_f64() * 1000.0,
                    "p99_ms": results.latencies.p99.as_secs_f64() * 1000.0,
                    "p999_ms": results.latencies.p999.as_secs_f64() * 1000.0,
                }
            },
            "metrics": {
                "avg_cpu_percent": metrics_summary.avg_cpu_percent,
                "max_cpu_percent": metrics_summary.max_cpu_percent,
                "avg_memory_mb": metrics_summary.avg_memory_mb,
                "max_memory_mb": metrics_summary.max_memory_mb,
                "avg_throughput_rps": metrics_summary.avg_throughput_rps,
                "peak_throughput_rps": metrics_summary.peak_throughput_rps,
            }
        });

        let json_str = serde_json::to_string_pretty(&report)?;
        fs::write(output_path, json_str)?;
        Ok(())
    }

    /// Build HTML report content
    fn build_html_report(results: &LoadTestResults, metrics: &MetricsSummary) -> String {
        let success_rate = (results.successful_operations as f64 / results.total_operations as f64) * 100.0;

        format!(
            r#"<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>ML Training Service - Load Test Report</title>
    <style>
        body {{
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            background: #f5f5f5;
        }}
        .header {{
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 30px;
            border-radius: 10px;
            margin-bottom: 30px;
        }}
        .header h1 {{
            margin: 0;
            font-size: 2.5em;
        }}
        .header .subtitle {{
            opacity: 0.9;
            margin-top: 10px;
        }}
        .metrics-grid {{
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 20px;
            margin-bottom: 30px;
        }}
        .metric-card {{
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }}
        .metric-label {{
            color: #666;
            font-size: 0.9em;
            margin-bottom: 5px;
        }}
        .metric-value {{
            font-size: 2em;
            font-weight: bold;
            color: #333;
        }}
        .metric-unit {{
            font-size: 0.6em;
            color: #999;
        }}
        .section {{
            background: white;
            padding: 30px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            margin-bottom: 20px;
        }}
        .section h2 {{
            margin-top: 0;
            color: #667eea;
            border-bottom: 2px solid #667eea;
            padding-bottom: 10px;
        }}
        table {{
            width: 100%;
            border-collapse: collapse;
        }}
        th, td {{
            padding: 12px;
            text-align: left;
            border-bottom: 1px solid #eee;
        }}
        th {{
            background: #f8f9fa;
            font-weight: 600;
            color: #667eea;
        }}
        .status-pass {{
            color: #28a745;
            font-weight: bold;
        }}
        .status-fail {{
            color: #dc3545;
            font-weight: bold;
        }}
        .progress-bar {{
            background: #e9ecef;
            border-radius: 4px;
            height: 20px;
            overflow: hidden;
        }}
        .progress-fill {{
            background: linear-gradient(90deg, #28a745, #20c997);
            height: 100%;
            transition: width 0.3s;
        }}
    </style>
</head>
<body>
    <div class="header">
        <h1>ML Training Service Load Test Report</h1>
        <div class="subtitle">Generated: {}</div>
    </div>

    <div class="metrics-grid">
        <div class="metric-card">
            <div class="metric-label">Total Operations</div>
            <div class="metric-value">{}</div>
        </div>
        <div class="metric-card">
            <div class="metric-label">Success Rate</div>
            <div class="metric-value">{:.2}<span class="metric-unit">%</span></div>
        </div>
        <div class="metric-card">
            <div class="metric-label">Throughput</div>
            <div class="metric-value">{:.2}<span class="metric-unit">ops/sec</span></div>
        </div>
        <div class="metric-card">
            <div class="metric-label">P95 Latency</div>
            <div class="metric-value">{:.2}<span class="metric-unit">ms</span></div>
        </div>
    </div>

    <div class="section">
        <h2>Test Results</h2>
        <table>
            <tr>
                <th>Metric</th>
                <th>Value</th>
                <th>Status</th>
            </tr>
            <tr>
                <td>Total Operations</td>
                <td>{}</td>
                <td class="status-pass">✓ PASS</td>
            </tr>
            <tr>
                <td>Successful Operations</td>
                <td>{}</td>
                <td class="status-pass">✓ PASS</td>
            </tr>
            <tr>
                <td>Failed Operations</td>
                <td>{}</td>
                <td class="{}">{}</td>
            </tr>
            <tr>
                <td>Total Duration</td>
                <td>{:.2}s</td>
                <td class="status-pass">✓ PASS</td>
            </tr>
            <tr>
                <td>Actual RPS</td>
                <td>{:.2}</td>
                <td class="status-pass">✓ PASS</td>
            </tr>
        </table>
    </div>

    <div class="section">
        <h2>Latency Distribution</h2>
        <table>
            <tr>
                <th>Percentile</th>
                <th>Latency (ms)</th>
            </tr>
            <tr>
                <td>Min</td>
                <td>{:.3}</td>
            </tr>
            <tr>
                <td>Mean</td>
                <td>{:.3}</td>
            </tr>
            <tr>
                <td>P50</td>
                <td>{:.3}</td>
            </tr>
            <tr>
                <td>P95</td>
                <td>{:.3}</td>
            </tr>
            <tr>
                <td>P99</td>
                <td>{:.3}</td>
            </tr>
            <tr>
                <td>P99.9</td>
                <td>{:.3}</td>
            </tr>
            <tr>
                <td>Max</td>
                <td>{:.3}</td>
            </tr>
        </table>
    </div>

    <div class="section">
        <h2>Resource Utilization</h2>
        <table>
            <tr>
                <th>Resource</th>
                <th>Average</th>
                <th>Peak</th>
            </tr>
            <tr>
                <td>CPU Usage</td>
                <td>{:.2}%</td>
                <td>{:.2}%</td>
            </tr>
            <tr>
                <td>Memory Usage</td>
                <td>{} MB</td>
                <td>{} MB</td>
            </tr>
            <tr>
                <td>Throughput</td>
                <td>{:.2} ops/sec</td>
                <td>{:.2} ops/sec</td>
            </tr>
        </table>
    </div>

    <div class="section">
        <h2>Success Rate Visualization</h2>
        <div class="progress-bar">
            <div class="progress-fill" style="width: {:.1}%"></div>
        </div>
        <p style="text-align: center; margin-top: 10px;">
            {:.2}% Success Rate ({} / {} operations)
        </p>
    </div>
</body>
</html>"#,
            chrono::Utc::now().to_rfc3339(),
            results.total_operations,
            success_rate,
            results.actual_rps,
            results.latencies.p95.as_secs_f64() * 1000.0,
            results.total_operations,
            results.successful_operations,
            results.failed_operations,
            if results.failed_operations == 0 { "status-pass" } else { "status-fail" },
            if results.failed_operations == 0 { "✓ PASS" } else { "✗ FAIL" },
            results.total_duration.as_secs_f64(),
            results.actual_rps,
            results.latencies.min.as_secs_f64() * 1000.0,
            results.latencies.mean.as_secs_f64() * 1000.0,
            results.latencies.p50.as_secs_f64() * 1000.0,
            results.latencies.p95.as_secs_f64() * 1000.0,
            results.latencies.p99.as_secs_f64() * 1000.0,
            results.latencies.p999.as_secs_f64() * 1000.0,
            results.latencies.max.as_secs_f64() * 1000.0,
            metrics.avg_cpu_percent,
            metrics.max_cpu_percent,
            metrics.avg_memory_mb,
            metrics.max_memory_mb,
            metrics.avg_throughput_rps,
            metrics.peak_throughput_rps,
            success_rate,
            success_rate,
            results.successful_operations,
            results.total_operations,
        )
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::time::Duration;
    use tempfile::TempDir;

    #[test]
    fn test_generate_html_report() {
        let temp_dir = TempDir::new().unwrap();
        let report_path = temp_dir.path().join("report.html");

        let results = LoadTestResults {
            total_operations: 1000,
            successful_operations: 990,
            failed_operations: 10,
            total_duration: Duration::from_secs(10),
            warmup_duration: Duration::from_secs(1),
            actual_rps: 100.0,
            latencies: super::super::load_generator::LatencyStats {
                min: Duration::from_millis(1),
                max: Duration::from_millis(50),
                mean: Duration::from_millis(10),
                p50: Duration::from_millis(9),
                p95: Duration::from_millis(20),
                p99: Duration::from_millis(35),
                p999: Duration::from_millis(45),
            },
        };

        let metrics = MetricsSummary {
            avg_cpu_percent: 45.0,
            max_cpu_percent: 75.0,
            avg_memory_mb: 500,
            max_memory_mb: 650,
            avg_throughput_rps: 98.5,
            peak_throughput_rps: 120.0,
        };

        ReportGenerator::generate_html_report(&report_path, &results, &metrics).unwrap();
        assert!(report_path.exists());
    }
}
