//! `diffsift report` — generate a review quality report from calibration data
//! and scan history.

use std::path::PathBuf;

use clap::Args;

use diffsift_core::calibration::CalibrationData;

#[derive(Args)]
pub struct ReportArgs {
    /// Path to the git repository
    #[arg(long, default_value = ".")]
    pub repo: PathBuf,

    /// Output format
    #[arg(long, default_value = "summary")]
    pub format: ReportFormat,
}

#[derive(Clone, Debug, clap::ValueEnum)]
pub enum ReportFormat {
    Summary,
    Json,
}

#[derive(serde::Serialize)]
struct ReportData {
    calibration_available: bool,
    rules_with_feedback: usize,
    total_reactions: u32,
    top_rules: Vec<RuleReport>,
    low_rated_rules: Vec<RuleReport>,
}

#[derive(serde::Serialize)]
struct RuleReport {
    rule_id: String,
    reactions: u32,
    positive_rate: f64,
}

pub fn run(args: ReportArgs) -> miette::Result<()> {
    let cal_path = args.repo.join(".diffsift").join("calibration.json");
    let cal = CalibrationData::load(&cal_path)
        .map_err(|e| miette::miette!("Failed to load calibration: {e}"))?;

    let report = match cal {
        Some(cal) => {
            let mut sorted: Vec<_> = cal
                .rule_weights
                .iter()
                .map(|(id, w)| RuleReport {
                    rule_id: id.clone(),
                    reactions: w.reactions,
                    positive_rate: w.positive_rate,
                })
                .collect();
            sorted.sort_by(|a, b| b.reactions.cmp(&a.reactions));

            let total_reactions: u32 = sorted.iter().map(|r| r.reactions).sum();
            let low_rated: Vec<RuleReport> = sorted
                .iter()
                .filter(|r| r.positive_rate < 0.5 && r.reactions >= 5)
                .map(|r| RuleReport {
                    rule_id: r.rule_id.clone(),
                    reactions: r.reactions,
                    positive_rate: r.positive_rate,
                })
                .collect();

            ReportData {
                calibration_available: true,
                rules_with_feedback: sorted.len(),
                total_reactions,
                top_rules: sorted.into_iter().take(10).collect(),
                low_rated_rules: low_rated,
            }
        }
        None => ReportData {
            calibration_available: false,
            rules_with_feedback: 0,
            total_reactions: 0,
            top_rules: Vec::new(),
            low_rated_rules: Vec::new(),
        },
    };

    match args.format {
        ReportFormat::Json => {
            let json = serde_json::to_string_pretty(&report)
                .map_err(|e| miette::miette!("JSON failed: {e}"))?;
            println!("{json}");
        }
        ReportFormat::Summary => print_report(&report),
    }

    Ok(())
}

fn print_report(report: &ReportData) {
    println!("DiffSift Review Quality Report");
    println!("==============================\n");

    if !report.calibration_available {
        println!("No calibration data found.");
        println!("Run `diffsift calibrate` to generate feedback data from PR reactions.\n");
        return;
    }

    println!(
        "  {} rules with feedback, {} total reactions\n",
        report.rules_with_feedback, report.total_reactions
    );

    if !report.top_rules.is_empty() {
        println!("Most-reviewed rules:");
        println!("  Rule       Reactions  Positive");
        println!("  ---------  ---------  --------");
        for r in &report.top_rules {
            println!(
                "  {:<9}  {:>9}  {:>7.0}%",
                r.rule_id,
                r.reactions,
                r.positive_rate * 100.0
            );
        }
        println!();
    }

    if !report.low_rated_rules.is_empty() {
        println!("Low-rated rules (consider tuning or disabling):");
        for r in &report.low_rated_rules {
            println!(
                "  {} — {:.0}% positive ({} reactions)",
                r.rule_id,
                r.positive_rate * 100.0,
                r.reactions
            );
        }
        println!();
    }

    if report.low_rated_rules.is_empty() && report.total_reactions > 0 {
        println!("  All rules have ≥50% positive feedback. No tuning needed.\n");
    }
}
