use std::io::Write;

use crate::error::{OKIError, OKIResult};
use crate::index::KmerIndex;

impl KmerIndex {
    /// Write a CSV table of all indexed kmers to `out`.
    ///
    /// Columns: `kmer`, then one column per genome (in index order).
    /// Values are counts (u32) when `use_counts = true`, otherwise 0/1.
    ///
    /// `force_presence` overrides `with_counts`: even if the index stores counts,
    /// the output uses 0/1 presence columns.
    ///
    /// The caller must have set the global kmer length (`obikseq::set_k`) before
    /// calling this method.
    pub fn dump<W: Write>(&self, out: &mut W, force_presence: bool, debug: bool) -> OKIResult<()> {

        let genomes    = &self.meta.genomes;
        let use_counts = self.meta.config.with_counts && !force_presence;
        let n_genomes  = genomes.len().max(1);
        let kmer_size  = self.kmer_size();

        // ── Header ────────────────────────────────────────────────────────────
        if debug {
            write!(out, "partition,layer,")?;
        }
        write!(out, "kmer")?;
        for g in genomes {
            write!(out, ",{}", g.label)?;
        }
        writeln!(out)?;

        // ── Rows ──────────────────────────────────────────────────────────────
        let n = self.n_partitions();
        for i in 0..n {
            if debug {
                self.partition
                    .iter_partition_kmers_located(i, use_counts, n_genomes, |part, layer, kmer, row| {
                        let seq = String::from_utf8(kmer.to_ascii())
                            .unwrap_or_else(|_| "?".repeat(kmer_size));
                        let _ = write!(out, "{part},{layer},{seq}");
                        for &v in row.iter() {
                            let _ = write!(out, ",{v}");
                        }
                        let _ = writeln!(out);
                    })
                    .map_err(OKIError::Partition)?;
            } else {
                self.partition
                    .iter_partition_kmers(i, use_counts, n_genomes, |kmer, row| {
                        let seq = String::from_utf8(kmer.to_ascii())
                            .unwrap_or_else(|_| "?".repeat(kmer_size));
                        let _ = write!(out, "{seq}");
                        for &v in row.iter() {
                            let _ = write!(out, ",{v}");
                        }
                        let _ = writeln!(out);
                    })
                    .map_err(OKIError::Partition)?;
            }
        }

        out.flush()?;
        Ok(())
    }
}
