use crate::error::{TuskError, TuskResult};
use serde_json::Value;
use std::fs::File;
use std::io::Write;

#[tauri::command]
pub async fn export_csv(
    path: String,
    columns: Vec<String>,
    rows: Vec<Vec<Value>>,
) -> TuskResult<()> {
    let file = File::create(&path)?;
    let mut wtr = csv::Writer::from_writer(file);

    wtr.write_record(&columns)
        .map_err(|e| TuskError::Export(e.to_string()))?;

    for row in &rows {
        let record: Vec<String> = row
            .iter()
            .map(|v| match v {
                Value::Null => String::new(),
                Value::String(s) => s.clone(),
                Value::Bool(b) => b.to_string(),
                Value::Number(n) => n.to_string(),
                _ => v.to_string(),
            })
            .collect();
        wtr.write_record(&record)
            .map_err(|e| TuskError::Export(e.to_string()))?;
    }

    wtr.flush().map_err(|e| TuskError::Export(e.to_string()))?;
    Ok(())
}

#[tauri::command]
pub async fn export_json(
    path: String,
    columns: Vec<String>,
    rows: Vec<Vec<Value>>,
) -> TuskResult<()> {
    let objects: Vec<serde_json::Map<String, Value>> = rows
        .iter()
        .map(|row| {
            columns
                .iter()
                .zip(row.iter())
                .map(|(col, val)| (col.clone(), val.clone()))
                .collect()
        })
        .collect();

    let json = serde_json::to_string_pretty(&objects)?;
    let mut file = File::create(&path)?;
    file.write_all(json.as_bytes())?;
    Ok(())
}
