///|
/// scMerge Demo - Single-cell batch correction using RUV4.
/// Demonstrates removal of unwanted variation (batch effects)
/// from synthetic single-cell expression data.
fn main {
  println("=== scMerge Demo ===")
  println("")

  // 1. Create synthetic single-cell data with batch effects
  println("--- Step 1: Create Synthetic Data ---")

  // Batch 1: 5 cells, 4 genes, base expression level ~1.0
  let batch1 = [
    [1.0, 2.0, 3.0, 4.0],
    [1.1, 2.1, 3.1, 4.1],
    [0.9, 1.9, 2.9, 3.9],
    [1.2, 2.2, 3.2, 4.2],
    [0.8, 1.8, 2.8, 3.8],
  ]

  // Batch 2: 5 cells, 4 genes, shifted by ~4.0 (batch effect)
  let batch2 = [
    [5.0, 6.0, 7.0, 8.0],
    [5.1, 6.1, 7.1, 8.1],
    [4.9, 5.9, 6.9, 7.9],
    [5.2, 6.2, 7.2, 8.2],
    [4.8, 5.8, 6.8, 7.8],
  ]

  // Batch 3: 5 cells, 4 genes, shifted by ~-2.0 (batch effect)
  let batch3 = [
    [-1.0, 0.0, 1.0, 2.0],
    [-0.9, 0.1, 1.1, 2.1],
    [-1.1, -0.1, 0.9, 1.9],
    [-0.8, 0.2, 1.2, 2.2],
    [-1.2, -0.2, 0.8, 1.8],
  ]

  let batches = [batch1, batch2, batch3]
  let n_batches = batches.length()
  let n_genes = batches[0][0].length()

  println("Batches: \{n_batches.to_string()}")
  println("Genes per cell: \{n_genes.to_string()}")

  // Show batch means before correction
  println("")
  println("Batch means before correction (gene 0):")
  let mut b = 0
  while b < n_batches {
    let batch = batches[b]
    let mut sum = 0.0
    let mut c = 0
    while c < batch.length() {
      sum = sum + batch[c][0]
      c = c + 1
    }
    let mean = sum / batch.length().to_double()
    println("  Batch \{b.to_string()}: mean = \{mean.to_string()}")
    b = b + 1
  }

  // 2. Find stably expressed genes (SEGs)
  println("")
  println("--- Step 2: Find Stably Expressed Genes (SEGs) ---")

  let seg = @src.scm_find_seg(batches, n_seg=2)
  println("SEG indices: \{repr(seg)}")
  // Interpret: which genes are most stable across batches
  let mut i = 0
  while i < seg.length() {
    println("  Gene \{seg[i].to_string()} is stably expressed")
    i = i + 1
  }

  // 3. Run scMerge batch correction
  println("")
  println("--- Step 3: Run scMerge Batch Correction ---")

  let result = @src.scmerge(batches, n_seg=2, n_factors=2)

  println(
    "Corrected data dimensions: \{result.corrected_data.length().to_string()} cells x \{result.corrected_data[0].length().to_string()} genes",
  )

  // 4. Show corrected batch means
  println("")
  println("--- Step 4: Batch Means After Correction ---")

  let mut offset = 0
  b = 0
  while b < n_batches {
    let batch_size = batches[b].length()
    let mut gene0_sum = 0.0
    let mut c = 0
    while c < batch_size {
      gene0_sum = gene0_sum + result.corrected_data[offset + c][0]
      c = c + 1
    }
    let mean = gene0_sum / batch_size.to_double()
    println(
      "  Batch \{b.to_string()}: corrected mean (gene 0) = \{mean.to_string()}",
    )
    offset = offset + batch_size
    b = b + 1
  }

  // 5. Show cell type labels
  println("")
  println("--- Step 5: Cell Type Labels ---")

  println("Cell type labels: \{repr(result.cell_type_labels)}")

  // 6. Show estimated batch factors
  println("")
  println("--- Step 6: Estimated Batch Factors ---")

  println("First 3 cells' batch factors:")
  let mut j = 0
  while j < 3 {
    println(
      "  Cell \{j.to_string()}: factors = \{repr(result.estimated_batch_factors[j])}",
    )
    j = j + 1
  }

  // 7. Print sample values from corrected data
  println("")
  println("--- Step 7: Sample Corrected Values ---")

  println("First 3 cells, first 2 genes:")
  let mut k = 0
  while k < 3 {
    println(
      "  Cell \{k.to_string()}: gene 0 = \{result.corrected_data[k][0].to_string()}, gene 1 = \{result.corrected_data[k][1].to_string()}",
    )
    k = k + 1
  }

  println("")
  println("Summary:")
  println(
    "  Total cells corrected: \{result.corrected_data.length().to_string()}",
  )
  println("  SEGs used: \{result.seg_genes.length().to_string()}")
  println("  Batch correction completed successfully")

  println("")
  println("Done!")
}