mod capture;
mod cdp;
mod clipboard;
mod cookies;
mod coverage;
mod download;
mod emulate;
mod frame;
mod interaction;
mod misc;
mod mouse;
mod navigation;
mod query;
mod route;
mod session_cmd;
mod state;
mod storage;
mod tab;
mod touch;
mod ws;

use night_fury_core::BrowserSession;

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

pub async fn dispatch(session: &BrowserSession, line: &str, mode: OutputMode) -> bool {
    let parts: Vec<&str> = line.splitn(4, ' ').collect();
    let cmd = parts[0].to_lowercase();

    match cmd.as_str() {
        "go" | "nav" | "navigate" => navigation::go(session, &parts[1..], mode).await,
        "back" => navigation::back(session, mode).await,
        "forward" => navigation::forward(session, mode).await,
        "reload" => navigation::reload(session, mode).await,
        "url" => navigation::url(session, mode).await,
        "title" => navigation::title(session, mode).await,

        "snap" | "s" | "snapshot" => capture::snap(session, mode).await,
        "screenshot" | "ss" => capture::screenshot(session, &parts[1..], mode).await,
        "eval" | "js" => capture::eval(session, line, mode).await,
        "pdf" => capture::pdf(session, &parts[1..], mode).await,

        "click" | "c" => interaction::click(session, &parts[1..], mode).await,
        "type" | "t" => interaction::type_text(session, line, &parts[1..], mode).await,
        "scroll" => interaction::scroll(session, &parts[1..], mode).await,
        "hover" => interaction::hover(session, &parts[1..], mode).await,
        "select" => interaction::select(session, &parts[1..], mode).await,
        "check" => interaction::check(session, &parts[1..], mode).await,
        "uncheck" => interaction::uncheck(session, &parts[1..], mode).await,
        "wait" | "sleep" => interaction::wait(session, &parts[1..], mode).await,

        "cookies" | "cookie" => cookies::dispatch(session, &parts[1..], mode).await,

        "tab" => tab::dispatch(session, &parts[1..], mode).await,
        "get" => query::dispatch(session, &parts[1..], mode).await,
        "is" => state::dispatch(session, &parts[1..], mode).await,
        "session" => session_cmd::dispatch(session, &parts[1..], mode).await,
        "frame" => frame::dispatch(session, &parts[1..], mode).await,
        "storage" => storage::dispatch(session, &parts[1..], mode).await,
        "clipboard" => clipboard::dispatch(session, &parts[1..], mode).await,
        "route" => route::dispatch(session, &parts[1..], mode).await,
        "emulate" => emulate::dispatch(session, &parts[1..], mode).await,
        "mouse" => mouse::dispatch(session, &parts[1..], mode).await,
        "touch" => touch::dispatch(session, &parts[1..], mode).await,
        "download" => download::dispatch(session, &parts[1..], mode).await,
        "ws" => ws::dispatch(session, &parts[1..], mode).await,
        "coverage" => coverage::dispatch(session, &parts[1..], mode).await,
        "cdp" => cdp::run(session, &parts[1..], mode).await,
        "viewport" => misc::viewport(session, &parts[1..], mode).await,
        "headers" => misc::headers(session, &parts[1..], mode).await,
        "auth" => misc::auth(session, &parts[1..], mode).await,

        "help" | "?" => print_help(mode),
        "quit" | "exit" | "q" => return true,

        _ => output_err(
            mode,
            &format!("Unknown command: {cmd}. Type 'help' for commands."),
        ),
    }
    false
}

fn print_help(mode: OutputMode) {
    match mode {
        OutputMode::Json => {
            let help = serde_json::json!({
                "ok": true,
                "data": {
                    "groups": [
                        {
                            "name": "Navigation",
                            "commands": [
                                {"cmd": "go <url>", "desc": "Navigate to URL", "aliases": ["nav"]},
                                {"cmd": "back", "desc": "History back"},
                                {"cmd": "forward", "desc": "History forward"},
                                {"cmd": "reload", "desc": "Reload page"},
                                {"cmd": "url", "desc": "Print current URL"},
                                {"cmd": "title", "desc": "Print page title"}
                            ]
                        },
                        {
                            "name": "Interaction",
                            "commands": [
                                {"cmd": "click <sel>", "desc": "Click element", "aliases": ["c"]},
                                {"cmd": "type <sel> <text>", "desc": "Type text", "aliases": ["t"]},
                                {"cmd": "scroll [px]", "desc": "Scroll (default: 600)"},
                                {"cmd": "hover <sel>", "desc": "Hover element"},
                                {"cmd": "select <sel> <value>", "desc": "Select dropdown option"},
                                {"cmd": "check <sel>", "desc": "Check checkbox"},
                                {"cmd": "uncheck <sel>", "desc": "Uncheck checkbox"},
                                {"cmd": "wait [ms]", "desc": "Wait (default: 1000)", "aliases": ["sleep"]}
                            ]
                        },
                        {
                            "name": "Capture",
                            "commands": [
                                {"cmd": "snap", "desc": "Page snapshot", "aliases": ["s", "snapshot"]},
                                {"cmd": "screenshot [file]", "desc": "Save PNG", "aliases": ["ss"]},
                                {"cmd": "pdf [file]", "desc": "Export PDF"},
                                {"cmd": "eval <js>", "desc": "Evaluate JavaScript", "aliases": ["js"]}
                            ]
                        },
                        {
                            "name": "Tabs",
                            "commands": [
                                {"cmd": "tab new [url]", "desc": "Open new tab"},
                                {"cmd": "tab switch <idx>", "desc": "Switch to tab"},
                                {"cmd": "tab list", "desc": "List tabs"},
                                {"cmd": "tab close [idx]", "desc": "Close tab"}
                            ]
                        },
                        {
                            "name": "Queries",
                            "commands": [
                                {"cmd": "get text <sel>", "desc": "Element text content"},
                                {"cmd": "get attr <sel> <name>", "desc": "Element attribute"},
                                {"cmd": "get html <sel>", "desc": "Element innerHTML"},
                                {"cmd": "get value <sel>", "desc": "Input value"},
                                {"cmd": "get count <sel>", "desc": "Count elements"},
                                {"cmd": "get box <sel>", "desc": "Bounding box"}
                            ]
                        },
                        {
                            "name": "State",
                            "commands": [
                                {"cmd": "is visible <sel>", "desc": "Check visibility"},
                                {"cmd": "is checked <sel>", "desc": "Check state"},
                                {"cmd": "is enabled <sel>", "desc": "Check enabled"}
                            ]
                        },
                        {
                            "name": "Cookies",
                            "commands": [
                                {"cmd": "cookies get", "desc": "List cookies"},
                                {"cmd": "cookies set <file>", "desc": "Inject from file"},
                                {"cmd": "cookies delete <n> <d>", "desc": "Delete cookie"},
                                {"cmd": "cookies clear", "desc": "Clear all"}
                            ]
                        },
                        {
                            "name": "Session",
                            "commands": [
                                {"cmd": "session save [file]", "desc": "Save session"},
                                {"cmd": "session load <file>", "desc": "Load session"}
                            ]
                        },
                        {
                            "name": "Routes",
                            "commands": [
                                {"cmd": "route block <pat>", "desc": "Block requests"},
                                {"cmd": "route fulfill <p> <s> <b>", "desc": "Mock response"},
                                {"cmd": "route capture <pat>", "desc": "Capture responses"},
                                {"cmd": "route list", "desc": "Show captured"},
                                {"cmd": "route clear", "desc": "Remove routes"}
                            ]
                        },
                        {
                            "name": "Frames",
                            "commands": [
                                {"cmd": "frame enter <sel>", "desc": "Switch to iframe"},
                                {"cmd": "frame main", "desc": "Back to main"}
                            ]
                        },
                        {
                            "name": "Storage",
                            "commands": [
                                {"cmd": "storage get <l|s> <k>", "desc": "Read value"},
                                {"cmd": "storage set <l|s> <k> <v>", "desc": "Write value"},
                                {"cmd": "storage clear <l|s>", "desc": "Clear all"}
                            ]
                        },
                        {
                            "name": "Clipboard",
                            "commands": [
                                {"cmd": "clipboard read", "desc": "Read clipboard"},
                                {"cmd": "clipboard write <txt>", "desc": "Write clipboard"}
                            ]
                        },
                        {
                            "name": "Mouse",
                            "commands": [
                                {"cmd": "mouse move <x> <y>", "desc": "Move cursor"},
                                {"cmd": "mouse wheel <delta>", "desc": "Scroll wheel"},
                                {"cmd": "mouse down [btn]", "desc": "Press button"},
                                {"cmd": "mouse up [btn]", "desc": "Release button"}
                            ]
                        },
                        {
                            "name": "Touch",
                            "commands": [
                                {"cmd": "touch tap <x> <y>", "desc": "Tap"},
                                {"cmd": "touch swipe <x1> <y1> <x2> <y2>", "desc": "Swipe"}
                            ]
                        },
                        {
                            "name": "Emulation",
                            "commands": [
                                {"cmd": "emulate tz <tz>", "desc": "Set timezone"},
                                {"cmd": "emulate locale <loc>", "desc": "Set locale"},
                                {"cmd": "emulate media <f> <v>", "desc": "Set media feature"},
                                {"cmd": "emulate geo <lat> <lng>", "desc": "Set geolocation"}
                            ]
                        },
                        {
                            "name": "Download",
                            "commands": [
                                {"cmd": "download path <dir>", "desc": "Set download dir"},
                                {"cmd": "download wait [sec]", "desc": "Wait for download"}
                            ]
                        },
                        {
                            "name": "WebSocket",
                            "commands": [
                                {"cmd": "ws start", "desc": "Start WS capture"},
                                {"cmd": "ws messages", "desc": "Get messages"}
                            ]
                        },
                        {
                            "name": "Coverage",
                            "commands": [
                                {"cmd": "coverage start", "desc": "Start coverage"},
                                {"cmd": "coverage stop", "desc": "Stop & report"}
                            ]
                        },
                        {
                            "name": "Other",
                            "commands": [
                                {"cmd": "cdp <method> [json]", "desc": "Raw CDP command"},
                                {"cmd": "viewport <w> <h>", "desc": "Resize viewport"},
                                {"cmd": "headers <json>", "desc": "Set extra headers"},
                                {"cmd": "auth <user> <pass>", "desc": "Set HTTP auth"},
                                {"cmd": "help", "desc": "Show this help"},
                                {"cmd": "quit", "desc": "Exit", "aliases": ["q"]}
                            ]
                        }
                    ],
                    "selector_hint": "Selectors: @e3 (ref), css #id, text Sign in, or bare CSS"
                }
            });
            println!(
                "{}",
                serde_json::to_string_pretty(&help).unwrap_or_default()
            );
        }
        OutputMode::Human => {
            println!(
                r#"Night Fury CLI — commands:

  Navigation:
    go <url>              Navigate to URL  (alias: nav)
    back                  History back
    forward               History forward
    reload                Reload page
    url                   Print current URL
    title                 Print page title

  Interaction:
    click <sel>           Click element  (alias: c)
    type <sel> <text>     Type text  (alias: t)
    scroll [px]           Scroll (default: 600)
    hover <sel>           Hover element
    select <sel> <value>  Select dropdown option
    check <sel>           Check checkbox
    uncheck <sel>         Uncheck checkbox
    wait [ms]             Wait (default: 1000)

  Capture:
    snap                  Page snapshot  (alias: s)
    screenshot [file]     Save PNG  (alias: ss)
    pdf [file]            Export PDF
    eval <js>             Evaluate JavaScript  (alias: js)

  Tabs:
    tab new [url]         Open new tab
    tab switch <idx>      Switch to tab
    tab list              List tabs
    tab close [idx]       Close tab

  Queries:
    get text <sel>        Element text content
    get attr <sel> <name> Element attribute
    get html <sel>        Element innerHTML
    get value <sel>       Input value
    get count <sel>       Count elements
    get box <sel>         Bounding box

  State:
    is visible <sel>      Check visibility
    is checked <sel>      Check state
    is enabled <sel>      Check enabled

  Cookies:
    cookies get           List cookies
    cookies set <file>    Inject from file
    cookies delete <n> <d> Delete cookie
    cookies clear         Clear all

  Session:
    session save [file]   Save session
    session load <file>   Load session

  Routes:
    route block <pat>     Block requests
    route fulfill <p> <s> <b>  Mock response
    route capture <pat>   Capture responses
    route list            Show captured
    route clear           Remove routes

  Frames:
    frame enter <sel>     Switch to iframe
    frame main            Back to main

  Storage:
    storage get <l|s> <k>       Read value
    storage set <l|s> <k> <v>   Write value
    storage clear <l|s>         Clear all

  Clipboard:
    clipboard read        Read clipboard
    clipboard write <txt> Write clipboard

  Mouse:
    mouse move <x> <y>    Move cursor
    mouse wheel <delta>   Scroll wheel
    mouse down [btn]      Press button
    mouse up [btn]        Release button

  Touch:
    touch tap <x> <y>     Tap
    touch swipe <x1> <y1> <x2> <y2>  Swipe

  Emulation:
    emulate tz <tz>       Set timezone
    emulate locale <loc>  Set locale
    emulate media <f> <v> Set media feature
    emulate geo <lat> <lng> Set geolocation

  Download:
    download path <dir>   Set download dir
    download wait [sec]   Wait for download

  WebSocket:
    ws start              Start WS capture
    ws messages           Get messages

  Coverage:
    coverage start        Start coverage
    coverage stop         Stop & report

  Other:
    cdp <method> [json]   Raw CDP command
    viewport <w> <h>      Resize viewport
    headers <json>        Set extra headers
    auth <user> <pass>    Set HTTP auth
    help                  Show this help
    quit                  Exit  (alias: q)

Selectors: @e3 (ref), css #id, text Sign in, or bare CSS"#
            );
        }
    }
}
