// Bioconductor nnSVG-inspired spatially variable gene analysis.

///|
fn main {
  let (expression, coordinates, gene_names) = @src.nnsvg_example_data()
  let config = @src.NnsvgConfig::create(
    n_neighbors=4,
    length_scale_grid=8,
    proportion_grid=8,
    refinement_steps=2,
    fdr_threshold=0.1,
  ) catch {
    NnsvgError(message) => abort("invalid nnSVG configuration: " + message)
  }

  let result = @src.nnsvg_with_config(
    expression,
    coordinates,
    config,
    gene_names~,
  ) catch {
    NnsvgError(message) => abort("nnSVG fit failed: " + message)
  }

  println("=== Direct nnSVG analysis ===")
  println(result.summary())
  println("rank\tgene\tLR\tp-value\tFDR\tprop_sv\tlength_scale")
  for gene in result.top(result.n_genes()) {
    println(
      gene.rank.to_string() +
      "\t" +
      gene.gene_name +
      "\t" +
      gene.likelihood_ratio.to_string() +
      "\t" +
      gene.p_value.to_string() +
      "\t" +
      gene.adjusted_p_value.to_string() +
      "\t" +
      gene.proportion_spatial_variance.to_string() +
      "\t" +
      gene.length_scale.to_string(),
    )
  }

  let counts = [
    [0.0, 0.0, 4.0, 5.0, 0.0, 0.0],
    [8.0, 9.0, 7.0, 8.0, 9.0, 8.0],
    [5.0, 5.0, 5.0, 5.0, 5.0, 5.0],
  ]
  let filter = @src.nnsvg_filter_genes(
    counts,
    ["low_expression", "spatial_candidate", "MT-ND1"],
    minimum_count=3.0,
    minimum_spot_percentage=50.0,
  ) catch {
    NnsvgError(message) => abort("nnSVG filtering failed: " + message)
  }
  println("\n=== Upstream-compatible gene filtering ===")
  println(
    "kept=" +
    filter.kept_indices.length().to_string() +
    ", low-expression=" +
    filter.removed_low_expression.length().to_string() +
    ", mitochondrial=" +
    filter.removed_mitochondrial.length().to_string(),
  )

  let experiment = @src.SpatialExperiment::new()
  ignore(@src.se_add_assay(experiment, "logcounts", expression))
  for gene_name in gene_names {
    ignore(@src.se_add_row(experiment, Map([("gene_name", gene_name)])))
  }
  for spot in 0..
      abort("nnSVG SpatialExperiment integration failed: " + message)
  }
  println("\n=== SpatialExperiment integration ===")
  println(
    "rowData fields written for " +
    integrated.experiment.row_data.length().to_string() +
    " genes; first-gene padj=" +
    integrated.experiment.row_data[0]["nnsvg_padj"],
  )
}