use night_fury_core::BrowserSession;
use serde_json::json;

use night_fury_cli_core::output::{output_err, output_ok, OutputMode};

pub async fn snap(session: &BrowserSession, mode: OutputMode) {
    match session.snapshot().await {
        Ok(snap) => {
            let rendered = night_fury_cli_core::display::render_snapshot(&snap);
            output_ok(
                mode,
                &rendered,
                json!({
                    "title": snap.title,
                    "url": snap.url,
                    "text": snap.text,
                    "elements": snap.elements.iter().map(|el| json!({
                        "idx": el.idx,
                        "role": el.role,
                        "name": el.name,
                        "disabled": el.disabled,
                        "required": el.required,
                        "href": el.href,
                    })).collect::<Vec<_>>(),
                }),
            );
        }
        Err(e) => output_err(mode, &e.to_string()),
    }
}

pub async fn screenshot(session: &BrowserSession, parts: &[&str], mode: OutputMode) {
    let path = parts.first().copied().unwrap_or("/tmp/nf.png");
    match session.screenshot().await {
        Ok(png) => {
            if let Err(e) = std::fs::write(path, &png) {
                output_err(mode, &format!("Error writing {path}: {e}"));
            } else {
                let msg = format!("Screenshot saved: {path}  ({} bytes)", png.len());
                output_ok(mode, &msg, json!({"path": path, "bytes": png.len()}));
            }
        }
        Err(e) => output_err(mode, &e.to_string()),
    }
}

pub async fn eval(session: &BrowserSession, line: &str, mode: OutputMode) {
    // Strip the command name prefix to get the JS expression
    let first_word_len = line.find(|c: char| c.is_whitespace()).unwrap_or(line.len());
    let js = line[first_word_len..].trim();
    if js.is_empty() {
        output_err(mode, "Usage: eval <javascript>");
        return;
    }
    match session.eval(js).await {
        Ok(v) => {
            let human = night_fury_cli_core::display::pretty_json(&v);
            output_ok(mode, &human, v);
        }
        Err(e) => output_err(mode, &e.to_string()),
    }
}

pub async fn pdf(session: &BrowserSession, parts: &[&str], mode: OutputMode) {
    let path = parts.first().copied().unwrap_or("/tmp/nf.pdf");
    match session.pdf().await {
        Ok(data) => {
            if let Err(e) = std::fs::write(path, &data) {
                output_err(mode, &format!("Error writing {path}: {e}"));
            } else {
                let msg = format!("PDF saved: {path}  ({} bytes)", data.len());
                output_ok(mode, &msg, json!({"path": path, "bytes": data.len()}));
            }
        }
        Err(e) => output_err(mode, &e.to_string()),
    }
}
