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

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

pub async fn dispatch(session: &BrowserSession, parts: &[&str], mode: OutputMode) {
    let sub = parts.first().copied().unwrap_or("");
    match sub {
        "visible" => is_visible(session, &parts[1..], mode).await,
        "checked" => is_checked(session, &parts[1..], mode).await,
        "enabled" => is_enabled(session, &parts[1..], mode).await,
        other => output_err(
            mode,
            &format!("Unknown is subcommand: {other}. Use 'visible', 'checked', or 'enabled'"),
        ),
    }
}

async fn is_visible(session: &BrowserSession, parts: &[&str], mode: OutputMode) {
    let sel = parts.join(" ");
    let sel = sel.trim();
    if sel.is_empty() {
        output_err(mode, "Usage: is visible <css-selector>");
        return;
    }
    match session.is_visible(sel).await {
        Ok(v) => output_ok(
            mode,
            &format!("{v}"),
            json!({"visible": v, "selector": sel}),
        ),
        Err(e) => output_err(mode, &e.to_string()),
    }
}

async fn is_checked(session: &BrowserSession, parts: &[&str], mode: OutputMode) {
    let sel = parts.join(" ");
    let sel = sel.trim();
    if sel.is_empty() {
        output_err(mode, "Usage: is checked <css-selector>");
        return;
    }
    match session.is_checked(sel).await {
        Ok(v) => output_ok(
            mode,
            &format!("{v}"),
            json!({"checked": v, "selector": sel}),
        ),
        Err(e) => output_err(mode, &e.to_string()),
    }
}

async fn is_enabled(session: &BrowserSession, parts: &[&str], mode: OutputMode) {
    let sel = parts.join(" ");
    let sel = sel.trim();
    if sel.is_empty() {
        output_err(mode, "Usage: is enabled <css-selector>");
        return;
    }
    match session.is_enabled(sel).await {
        Ok(v) => output_ok(
            mode,
            &format!("{v}"),
            json!({"enabled": v, "selector": sel}),
        ),
        Err(e) => output_err(mode, &e.to_string()),
    }
}
