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

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

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub(super) enum FrameSub {
    Enter,
    Main,
    Unknown,
}

pub(super) fn resolve_frame_sub(s: &str) -> FrameSub {
    match s {
        "enter" => FrameSub::Enter,
        "main" => FrameSub::Main,
        _ => FrameSub::Unknown,
    }
}

pub async fn dispatch(session: &BrowserSession, parts: &[&str], mode: OutputMode) {
    let sub = parts.first().copied().unwrap_or("");
    match resolve_frame_sub(sub) {
        FrameSub::Enter => enter(session, &parts[1..], mode).await,
        FrameSub::Main => main_frame(session, mode).await,
        FrameSub::Unknown => output_err(
            mode,
            &format!("Unknown frame subcommand: {sub}. Use 'enter <css-selector>' or 'main'"),
        ),
    }
}

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

async fn main_frame(session: &BrowserSession, mode: OutputMode) {
    match session.switch_to_main_frame().await {
        Ok(msg) => output_ok(mode, &msg, json!({"action": "frame_main"})),
        Err(e) => output_err(mode, &e.to_string()),
    }
}

#[cfg(test)]
mod tests {
    use super::{resolve_frame_sub, FrameSub};

    #[test]
    fn resolves_known_subcommands() {
        assert_eq!(resolve_frame_sub("enter"), FrameSub::Enter);
        assert_eq!(resolve_frame_sub("main"), FrameSub::Main);
    }

    #[test]
    fn unknown_subcommand_returns_unknown() {
        assert_eq!(resolve_frame_sub(""), FrameSub::Unknown);
        assert_eq!(resolve_frame_sub("exit"), FrameSub::Unknown);
    }
}
