use crate::cli::{eval, DEFAULT_PORT};
use anyhow::Result;
use clap::Parser;

#[derive(Parser)]
pub struct Args {
    /// Print as JSON instead of indented tree.
    #[arg(long)]
    pub json: bool,

    #[arg(long, default_value_t = 5)]
    pub timeout_secs: u64,

    #[arg(long, default_value_t = DEFAULT_PORT)]
    pub port: u16,
}

pub fn run(args: Args) -> Result<()> {
    let code = "return window.adomStep ? window.adomStep.listComponents() : { error: 'adomStep not loaded yet' };";
    let result = eval::eval_snippet(code, args.timeout_secs, args.port, true)?;

    if args.json {
        println!("{}", serde_json::to_string_pretty(&result)?);
        return Ok(());
    }

    if let Some(err) = result.get("error").and_then(|v| v.as_str()) {
        eprintln!("ERROR: {err}");
        return Err(anyhow::anyhow!("{err}"));
    }
    let empty = vec![];
    let nodes = result.as_array().unwrap_or(&empty);
    for n in nodes {
        let depth = n.get("depth").and_then(|v| v.as_u64()).unwrap_or(0) as usize;
        let name = n.get("name").and_then(|v| v.as_str()).unwrap_or("?");
        let visible = n.get("visible").and_then(|v| v.as_bool()).unwrap_or(true);
        let mark = if visible { "●" } else { "○" };
        let pad = "  ".repeat(depth);
        println!("{}{} {}", pad, mark, name);
    }
    Ok(())
}