/// Generate synthetic EEG CSV files for testing steegformer.
///
/// Usage:
///   cargo run --bin gen_sample_eeg --release -- --output sample.csv

use clap::Parser;
use std::io::Write;

#[derive(Parser, Debug)]
#[command(about = "Generate synthetic EEG CSV for testing")]
struct Args {
    /// Output CSV file path.
    #[arg(long, short, default_value = "data/sample.csv")]
    output: String,

    /// Number of channels (max 19 for 10-20 system).
    #[arg(long, default_value_t = 19)]
    channels: usize,

    /// Duration in seconds.
    #[arg(long, default_value_t = 6.0)]
    duration: f32,

    /// Sampling rate in Hz.
    #[arg(long, default_value_t = 128.0)]
    sfreq: f32,
}

fn main() -> anyhow::Result<()> {
    let args = Args::parse();
    let channel_names = steegformer::STANDARD_10_20;
    let n_ch = args.channels.min(channel_names.len());
    let n_t = (args.duration * args.sfreq) as usize;
    let dt = 1.0 / args.sfreq;

    if let Some(parent) = std::path::Path::new(&args.output).parent() {
        std::fs::create_dir_all(parent)?;
    }
    let mut f = std::fs::File::create(&args.output)?;

    writeln!(f, "# Generated by steegformer gen_sample_eeg")?;
    writeln!(f, "# sfreq={} channels={} duration={}s samples={}",
        args.sfreq, n_ch, args.duration, n_t)?;

    write!(f, "timestamp")?;
    for ch in 0..n_ch {
        write!(f, ",{}", channel_names[ch])?;
    }
    writeln!(f)?;

    let mut noise_state: u32 = 0xDEAD_BEEF;
    for t in 0..n_t {
        let time = t as f32 * dt;
        write!(f, "{time:.9e}")?;
        for ch in 0..n_ch {
            let alpha = (2.0 * std::f32::consts::PI * (9.5 + ch as f32 * 0.3) * time).sin() * 20e-6;
            let theta = (2.0 * std::f32::consts::PI * (5.0 + ch as f32 * 0.1) * time).sin() * 15e-6;
            let beta  = (2.0 * std::f32::consts::PI * (20.0 + ch as f32 * 0.7) * time).sin() * 5e-6;
            noise_state ^= noise_state << 13;
            noise_state ^= noise_state >> 17;
            noise_state ^= noise_state << 5;
            let noise = (noise_state as f32 / u32::MAX as f32 - 0.5) * 3e-6;
            let val = alpha + theta + beta + noise;
            write!(f, ",{val:.9e}")?;
        }
        writeln!(f)?;
    }

    let size = std::fs::metadata(&args.output)?.len();
    println!("Generated {n_ch} channels × {n_t} samples ({:.1}s @ {} Hz)",
        args.duration, args.sfreq);
    println!("  → {} ({:.1} KB)", args.output, size as f64 / 1024.0);
    Ok(())
}
