use anyhow::Result;
use clap::Args;
use std::collections::HashMap;
use std::path::PathBuf;
use crate::runner;
use crate::report::generate_html_report;

#[derive(Args)]
pub struct ReportArgs {
    #[arg(required = true)]
    pub test_dirs: Vec<String>,
    #[arg(short, long)]
    pub output: Option<String>,
    #[arg(long, help = "Generate HTML report with charts")]
    pub html: bool,
}

pub fn run(args: ReportArgs) -> Result<()> {
    println!("\ncreating report from {} test(s)\n", args.test_dirs.len());

    let mut all_results = HashMap::new();
    for dir in &args.test_dirs {
        match runner::load_results_payload(dir) {
            Ok(payload) => {
                for (name, results) in payload.results {
                    all_results.insert(format!("{}/{}", dir, name), results);
                }
            }
            Err(e) => eprintln!("warning: could not load {}: {}", dir, e),
        }
    }

    if all_results.is_empty() {
        println!("no results found");
        return Ok(());
    }

    runner::print_results_summary(&all_results);

    let output_dir = args.output.unwrap_or_else(|| ".".to_string());
    std::fs::create_dir_all(&output_dir)?;

    let report_path = PathBuf::from(&output_dir).join("report.json");
    std::fs::write(&report_path, serde_json::to_string_pretty(&all_results)?)?;
    println!("\nreport saved to: {}", report_path.display());

    if args.html {
        let title = if args.test_dirs.len() == 1 {
            args.test_dirs[0].clone()
        } else {
            format!("{} tests", args.test_dirs.len())
        };
        let html = generate_html_report(&all_results, &title);
        let html_path = PathBuf::from(&output_dir).join("report.html");
        std::fs::write(&html_path, html)?;
        println!("html report saved to: {}", html_path.display());
    }

    Ok(())
}
