///|
/// AUCell example: gene set scoring for single-cell data using AUC.
///
/// AUCell uses Area Under Curve (AUC) to score gene sets per cell.
/// It ranks genes by expression and computes the enrichment of gene sets.
///
/// Run: moon run examples/aucell_demo/main.mbt
fn main {
  // === Create synthetic single-cell expression data ===
  let gene_names = [
    "TP53", "BRCA1", "MYC", "CCND1", "BCL2", "BAX", "CASP3", "CDK1", "E2F1", "RB1",
  ]
  let cell_names = [
    "CellTypeA_1", "CellTypeA_2", "CellTypeA_3", "CellTypeB_1", "CellTypeB_2", "CellTypeB_3",
  ]

  // Expression matrix (cells × genes)
  let expression : Array[Array[Double]] = [
    // TP53  BRCA1  MYC   CCND1  BCL2  BAX   CASP3  CDK1  E2F1  RB1
    [10.0, 8.0, 2.0, 1.0, 9.0, 7.0, 8.0, 1.0, 2.0, 3.0], // CellTypeA_1
    [9.0, 7.0, 3.0, 2.0, 8.0, 6.0, 7.0, 2.0, 3.0, 4.0], // CellTypeA_2
    [11.0, 9.0, 1.0, 0.5, 10.0, 8.0, 9.0, 0.5, 1.0, 2.0], // CellTypeA_3
    [2.0, 3.0, 10.0, 9.0, 1.0, 2.0, 1.0, 10.0, 9.0, 8.0], // CellTypeB_1
    [1.0, 2.0, 11.0, 10.0, 0.5, 1.0, 0.5, 11.0, 10.0, 9.0], // CellTypeB_2
    [3.0, 4.0, 8.0, 7.0, 2.0, 3.0, 2.0, 8.0, 7.0, 6.0], // CellTypeB_3
  ]

  // === Define gene sets (signatures) ===
  let apoptosis_genes = ["TP53", "BAX", "CASP3", "BCL2"]
  let apoptosis_set = @bio.GeneSet::new("Apoptosis", apoptosis_genes)

  let cell_cycle_genes = ["MYC", "CCND1", "CDK1", "E2F1", "RB1"]
  let cell_cycle_set = @bio.GeneSet::new("Cell_Cycle", cell_cycle_genes)

  let dna_repair_genes = ["BRCA1", "TP53"]
  let dna_repair_set = @bio.GeneSet::new("DNA_Repair", dna_repair_genes)

  let gene_sets = [apoptosis_set, cell_cycle_set, dna_repair_set]

  // === Create AUCell data and run analysis ===
  println("=== AUCell Gene Set Scoring ===")
  println("  Cells: \{cell_names.length()}")
  println("  Genes: \{gene_names.length()}")
  println("  Gene sets: \{gene_sets.length()}")

  let data = @bio.AUCellData::new(expression, cell_names, gene_names, gene_sets)
  let result = @bio.run_aucell(data)

  // === Display raw scores ===
  println("\n=== Raw AUCell Scores ===")
  let mut header = "Cell\t"
  for gs_name in result.gene_set_names {
    header = header + gs_name + "\t"
  }
  println(header)

  let mut i = 0
  while i < result.cell_names.length() {
    let mut line = result.cell_names[i] + "\t"
    let mut j = 0
    while j < result.score_matrix[i].length() {
      let val = result.score_matrix[i][j]
      line = line + val.to_string() + "\t"
      j = j + 1
    }
    println(line)
    i = i + 1
  }

  // === Normalize scores ===
  println("\n=== Normalized AUCell Scores (min-max per gene set) ===")
  let normalized = @bio.normalize_aucell_scores(result)
  let mut header2 = "Cell\t"
  for gs_name in normalized.gene_set_names {
    header2 = header2 + gs_name + "\t"
  }
  println(header2)

  let mut c = 0
  while c < normalized.cell_names.length() {
    let mut line = normalized.cell_names[c] + "\t"
    let mut s = 0
    while s < normalized.score_matrix[c].length() {
      let val = normalized.score_matrix[c][s]
      line = line + val.to_string() + "\t"
      s = s + 1
    }
    println(line)
    c = c + 1
  }

  // === Get cell scores ===
  println("\n=== Gene Set Scores for CellTypeA_1 ===")
  let cell_scores = @bio.get_cell_scores(normalized, "CellTypeA_1")
  let mut cs = 0
  while cs < normalized.gene_set_names.length() {
    println(
      "  \{normalized.gene_set_names[cs]}: \{cell_scores[cs].to_string()}",
    )
    cs = cs + 1
  }

  // === Get gene set scores across cells ===
  println("\n=== Apoptosis Scores Across Cells ===")
  let apoptosis_scores = @bio.get_set_scores(normalized, "Apoptosis")
  let mut a = 0
  while a < normalized.cell_names.length() {
    println("  \{normalized.cell_names[a]}: \{apoptosis_scores[a].to_string()}")
    a = a + 1
  }

  println("\nDone!")
}