mod common;

use std::sync::Arc;
use std::time::Duration;

use common::MockTransport;
use sgclaw::pipe::{Action, AgentMessage, BrowserMessage, BrowserPipeTool, Timing};
use sgclaw::security::MacPolicy;
use sgclaw::skill::zhihu_navigation::{execute, load_catalog, ZhihuNavigateRequest};

fn test_policy() -> MacPolicy {
    MacPolicy::from_json_str(
        r#"{
            "version": "1.0",
            "domains": { "allowed": ["www.zhihu.com", "zhuanlan.zhihu.com"] },
            "pipe_actions": {
                "allowed": ["click", "navigate", "getText", "waitForSelector"],
                "blocked": []
            }
        }"#,
    )
    .unwrap()
}

fn response(seq: u64, data: serde_json::Value) -> BrowserMessage {
    BrowserMessage::Response {
        seq,
        success: true,
        data,
        aom_snapshot: vec![],
        timing: Timing {
            queue_ms: 1,
            exec_ms: 10,
        },
    }
}

#[test]
fn load_catalog_preserves_confirmed_content_analysis_route() {
    let catalog = load_catalog().unwrap();

    assert_eq!(catalog.domains["creator"], "www.zhihu.com");
    assert_eq!(
        catalog.routes["content_analysis"].url,
        "https://www.zhihu.com/creator/analytics/work/all"
    );
    assert_eq!(
        catalog.targets["content_analysis"].route_ref.as_deref(),
        Some("content_analysis")
    );
    assert!(catalog.routes["content_analysis"]
        .aliases
        .iter()
        .any(|alias| alias == "知乎内容分析页面"));
}

#[test]
fn load_catalog_includes_top_level_navigation_targets() {
    let catalog = load_catalog().unwrap();

    assert_eq!(catalog.routes["home"].url, "https://www.zhihu.com/");
    assert_eq!(catalog.routes["hot_list"].url, "https://www.zhihu.com/hot");
    assert_eq!(
        catalog.routes["column_home"].url,
        "https://zhuanlan.zhihu.com/"
    );
    assert_eq!(
        catalog.routes["messages_page"].url,
        "https://www.zhihu.com/messages"
    );
    assert_eq!(
        catalog.routes["notifications_page"].url,
        "https://www.zhihu.com/notifications"
    );
    assert_eq!(
        catalog.targets["messages_unread_tab"]
            .component_ref
            .as_deref(),
        Some("messages_tab_unread")
    );
    assert_eq!(
        catalog.targets["notifications_replies_tab"]
            .component_ref
            .as_deref(),
        Some("notifications_tab_replies")
    );
    assert_eq!(
        catalog.targets["notifications_settings_menu"]
            .component_ref
            .as_deref(),
        Some("notifications_settings_menu")
    );
    assert_eq!(
        catalog.targets["profile_page"].flow_ref.as_deref(),
        Some("open_profile_from_avatar_menu")
    );
    assert_eq!(
        catalog.targets["notifications_menu"].flow_ref.as_deref(),
        Some("open_notifications_menu")
    );
    assert_eq!(
        catalog.targets["search_box"].component_ref.as_deref(),
        Some("top_nav_search")
    );
    assert_eq!(
        catalog.components["creator_write_button"]
            .result_domain_ref
            .as_deref(),
        Some("editor")
    );
}

#[test]
fn load_catalog_includes_expanded_profile_and_settings_flows() {
    let catalog = load_catalog().unwrap();

    assert_eq!(
        catalog.targets["profile_answers_tab"].flow_ref.as_deref(),
        Some("open_profile_answers_tab")
    );
    assert_eq!(
        catalog.targets["profile_followers_tab"].flow_ref.as_deref(),
        Some("open_profile_followers_tab")
    );
    assert_eq!(
        catalog.targets["settings_account_menu"].flow_ref.as_deref(),
        Some("open_account_settings_from_avatar_menu")
    );
    assert_eq!(
        catalog.targets["settings_privacy_menu"].flow_ref.as_deref(),
        Some("open_privacy_settings_from_avatar_menu")
    );
    assert_eq!(
        catalog.targets["settings_security_menu"]
            .flow_ref
            .as_deref(),
        Some("open_security_settings_from_avatar_menu")
    );
}

#[test]
fn zhihu_navigation_skill_opens_content_analysis_page() {
    let transport = Arc::new(MockTransport::new(vec![response(
        1,
        serde_json::json!({ "url": "https://www.zhihu.com/creator/analytics/work/all" }),
    )]));
    let browser_tool = BrowserPipeTool::new(
        transport.clone(),
        test_policy(),
        vec![1, 2, 3, 4, 5, 6, 7, 8],
    )
    .with_response_timeout(Duration::from_secs(1));

    let result = execute(
        transport.as_ref(),
        &browser_tool,
        ZhihuNavigateRequest {
            page: "content_analysis".to_string(),
            ensure_loaded: true,
        },
    )
    .unwrap();
    let sent = transport.sent_messages();

    assert_eq!(
        result.summary,
        "知乎页面已打开：内容分析 (https://www.zhihu.com/creator/analytics/work/all)"
    );
    assert_eq!(result.page, "content_analysis");
    assert_eq!(
        result.final_url,
        "https://www.zhihu.com/creator/analytics/work/all"
    );
    assert_eq!(sent.len(), 2);
    assert!(matches!(
        &sent[0],
        AgentMessage::LogEntry { level, message }
            if level == "info"
                && message == "navigate https://www.zhihu.com/creator/analytics/work/all"
    ));
    assert!(matches!(
        &sent[1],
        AgentMessage::Command { seq, action, .. }
            if *seq == 1 && action == &Action::Navigate
    ));
}

#[test]
fn zhihu_navigation_skill_clicks_creator_write_button() {
    let transport = Arc::new(MockTransport::new(vec![
        response(
            1,
            serde_json::json!({ "url": "https://www.zhihu.com/creator" }),
        ),
        response(
            2,
            serde_json::json!({ "clicked": true, "url": "https://zhuanlan.zhihu.com/write" }),
        ),
        response(
            3,
            serde_json::json!({ "ready": true, "url": "https://zhuanlan.zhihu.com/write" }),
        ),
    ]));
    let browser_tool = BrowserPipeTool::new(
        transport.clone(),
        test_policy(),
        vec![1, 2, 3, 4, 5, 6, 7, 8],
    )
    .with_response_timeout(Duration::from_secs(1));

    let result = execute(
        transport.as_ref(),
        &browser_tool,
        ZhihuNavigateRequest {
            page: "creator_write_button".to_string(),
            ensure_loaded: true,
        },
    )
    .unwrap();
    let sent = transport.sent_messages();

    assert_eq!(
        result.summary,
        "知乎入口已打开：写文章入口按钮 (https://zhuanlan.zhihu.com/write)"
    );
    assert_eq!(result.page, "creator_write_button");
    assert_eq!(result.final_url, "https://zhuanlan.zhihu.com/write");
    assert_eq!(sent.len(), 6);
    assert!(matches!(
        &sent[0],
        AgentMessage::LogEntry { level, message }
            if level == "info" && message == "navigate https://www.zhihu.com/creator"
    ));
    assert!(matches!(
        &sent[1],
        AgentMessage::Command { seq, action, .. }
            if *seq == 1 && action == &Action::Navigate
    ));
    assert!(matches!(
        &sent[2],
        AgentMessage::LogEntry { level, message }
            if level == "info" && message == "click 写文章入口按钮"
    ));
    assert!(matches!(
        &sent[3],
        AgentMessage::Command { seq, action, security, .. }
            if *seq == 2 && action == &Action::Click && security.expected_domain == "www.zhihu.com"
    ));
    assert!(matches!(
        &sent[4],
        AgentMessage::LogEntry { level, message }
            if level == "info" && message.contains("wait for textarea")
    ));
    assert!(matches!(
        &sent[5],
        AgentMessage::Command { seq, action, security, .. }
            if *seq == 3 && action == &Action::WaitForSelector && security.expected_domain == "zhuanlan.zhihu.com"
    ));
}

#[test]
fn zhihu_navigation_skill_opens_notifications_menu_flow() {
    let transport = Arc::new(MockTransport::new(vec![
        response(1, serde_json::json!({ "url": "https://www.zhihu.com/" })),
        response(2, serde_json::json!({ "clicked": true })),
    ]));
    let browser_tool = BrowserPipeTool::new(
        transport.clone(),
        test_policy(),
        vec![1, 2, 3, 4, 5, 6, 7, 8],
    )
    .with_response_timeout(Duration::from_secs(1));

    let result = execute(
        transport.as_ref(),
        &browser_tool,
        ZhihuNavigateRequest {
            page: "notifications_menu".to_string(),
            ensure_loaded: true,
        },
    )
    .unwrap();
    let sent = transport.sent_messages();

    assert_eq!(result.summary, "知乎菜单已打开：通知菜单");
    assert_eq!(result.page, "notifications_menu");
    assert_eq!(result.final_url, "https://www.zhihu.com/");
    assert_eq!(sent.len(), 4);
    assert!(matches!(
        &sent[0],
        AgentMessage::LogEntry { level, message }
            if level == "info" && message == "navigate https://www.zhihu.com/"
    ));
    assert!(matches!(
        &sent[1],
        AgentMessage::Command { seq, action, .. }
            if *seq == 1 && action == &Action::Navigate
    ));
    assert!(matches!(
        &sent[2],
        AgentMessage::LogEntry { level, message }
            if level == "info" && message == "click 通知菜单"
    ));
    assert!(matches!(
        &sent[3],
        AgentMessage::Command { seq, action, security, .. }
            if *seq == 2 && action == &Action::Click && security.expected_domain == "www.zhihu.com"
    ));
}

#[test]
fn zhihu_navigation_skill_opens_profile_page_from_avatar_menu() {
    let transport = Arc::new(MockTransport::new(vec![
        response(1, serde_json::json!({ "url": "https://www.zhihu.com/" })),
        response(2, serde_json::json!({ "clicked": true })),
        response(
            3,
            serde_json::json!({ "clicked": true, "url": "https://www.zhihu.com/people/test-user" }),
        ),
    ]));
    let browser_tool = BrowserPipeTool::new(
        transport.clone(),
        test_policy(),
        vec![1, 2, 3, 4, 5, 6, 7, 8],
    )
    .with_response_timeout(Duration::from_secs(1));

    let result = execute(
        transport.as_ref(),
        &browser_tool,
        ZhihuNavigateRequest {
            page: "profile_page".to_string(),
            ensure_loaded: true,
        },
    )
    .unwrap();
    let sent = transport.sent_messages();

    assert_eq!(
        result.summary,
        "知乎导航已完成：个人主页 (https://www.zhihu.com/people/test-user)"
    );
    assert_eq!(result.page, "profile_page");
    assert_eq!(result.final_url, "https://www.zhihu.com/people/test-user");
    assert_eq!(sent.len(), 6);
    assert!(matches!(
        &sent[0],
        AgentMessage::LogEntry { level, message }
            if level == "info" && message == "navigate https://www.zhihu.com/"
    ));
    assert!(matches!(
        &sent[1],
        AgentMessage::Command { seq, action, .. }
            if *seq == 1 && action == &Action::Navigate
    ));
    assert!(matches!(
        &sent[2],
        AgentMessage::LogEntry { level, message }
            if level == "info" && message == "click 头像菜单"
    ));
    assert!(matches!(
        &sent[3],
        AgentMessage::Command { seq, action, .. }
            if *seq == 2 && action == &Action::Click
    ));
    assert!(matches!(
        &sent[4],
        AgentMessage::LogEntry { level, message }
            if level == "info" && message == "click 个人主页入口"
    ));
    assert!(matches!(
        &sent[5],
        AgentMessage::Command { seq, action, security, .. }
            if *seq == 3 && action == &Action::Click && security.expected_domain == "www.zhihu.com"
    ));
}

#[test]
fn zhihu_navigation_skill_opens_profile_answers_tab_from_avatar_menu() {
    let transport = Arc::new(MockTransport::new(vec![
        response(1, serde_json::json!({ "url": "https://www.zhihu.com/" })),
        response(2, serde_json::json!({ "clicked": true })),
        response(
            3,
            serde_json::json!({ "clicked": true, "url": "https://www.zhihu.com/people/test-user" }),
        ),
        response(
            4,
            serde_json::json!({ "clicked": true, "url": "https://www.zhihu.com/people/test-user/answers" }),
        ),
    ]));
    let browser_tool = BrowserPipeTool::new(
        transport.clone(),
        test_policy(),
        vec![1, 2, 3, 4, 5, 6, 7, 8],
    )
    .with_response_timeout(Duration::from_secs(1));

    let result = execute(
        transport.as_ref(),
        &browser_tool,
        ZhihuNavigateRequest {
            page: "profile_answers_tab".to_string(),
            ensure_loaded: true,
        },
    )
    .unwrap();
    let sent = transport.sent_messages();

    assert_eq!(
        result.summary,
        "知乎导航已完成：回答分栏 (https://www.zhihu.com/people/test-user/answers)"
    );
    assert_eq!(result.page, "profile_answers_tab");
    assert_eq!(
        result.final_url,
        "https://www.zhihu.com/people/test-user/answers"
    );
    assert_eq!(sent.len(), 8);
    assert!(matches!(
        &sent[0],
        AgentMessage::LogEntry { level, message }
            if level == "info" && message == "navigate https://www.zhihu.com/"
    ));
    assert!(matches!(
        &sent[1],
        AgentMessage::Command { seq, action, .. }
            if *seq == 1 && action == &Action::Navigate
    ));
    assert!(matches!(
        &sent[2],
        AgentMessage::LogEntry { level, message }
            if level == "info" && message == "click 头像菜单"
    ));
    assert!(matches!(
        &sent[3],
        AgentMessage::Command { seq, action, .. }
            if *seq == 2 && action == &Action::Click
    ));
    assert!(matches!(
        &sent[4],
        AgentMessage::LogEntry { level, message }
            if level == "info" && message == "click 个人主页入口"
    ));
    assert!(matches!(
        &sent[5],
        AgentMessage::Command { seq, action, .. }
            if *seq == 3 && action == &Action::Click
    ));
    assert!(matches!(
        &sent[6],
        AgentMessage::LogEntry { level, message }
            if level == "info" && message == "click 回答分栏"
    ));
    assert!(matches!(
        &sent[7],
        AgentMessage::Command { seq, action, security, .. }
            if *seq == 4 && action == &Action::Click && security.expected_domain == "www.zhihu.com"
    ));
}

#[test]
fn zhihu_navigation_skill_opens_account_settings_from_avatar_menu() {
    let transport = Arc::new(MockTransport::new(vec![
        response(1, serde_json::json!({ "url": "https://www.zhihu.com/" })),
        response(2, serde_json::json!({ "clicked": true })),
        response(
            3,
            serde_json::json!({ "clicked": true, "url": "https://www.zhihu.com/settings/account" }),
        ),
    ]));
    let browser_tool = BrowserPipeTool::new(
        transport.clone(),
        test_policy(),
        vec![1, 2, 3, 4, 5, 6, 7, 8],
    )
    .with_response_timeout(Duration::from_secs(1));

    let result = execute(
        transport.as_ref(),
        &browser_tool,
        ZhihuNavigateRequest {
            page: "settings_account_menu".to_string(),
            ensure_loaded: true,
        },
    )
    .unwrap();
    let sent = transport.sent_messages();

    assert_eq!(
        result.summary,
        "知乎导航已完成：账号设置菜单 (https://www.zhihu.com/settings/account)"
    );
    assert_eq!(result.page, "settings_account_menu");
    assert_eq!(result.final_url, "https://www.zhihu.com/settings/account");
    assert_eq!(sent.len(), 6);
    assert!(matches!(
        &sent[0],
        AgentMessage::LogEntry { level, message }
            if level == "info" && message == "navigate https://www.zhihu.com/"
    ));
    assert!(matches!(
        &sent[1],
        AgentMessage::Command { seq, action, .. }
            if *seq == 1 && action == &Action::Navigate
    ));
    assert!(matches!(
        &sent[2],
        AgentMessage::LogEntry { level, message }
            if level == "info" && message == "click 头像菜单"
    ));
    assert!(matches!(
        &sent[3],
        AgentMessage::Command { seq, action, .. }
            if *seq == 2 && action == &Action::Click
    ));
    assert!(matches!(
        &sent[4],
        AgentMessage::LogEntry { level, message }
            if level == "info" && message == "click 账号设置菜单"
    ));
    assert!(matches!(
        &sent[5],
        AgentMessage::Command { seq, action, security, .. }
            if *seq == 3 && action == &Action::Click && security.expected_domain == "www.zhihu.com"
    ));
}

#[test]
fn zhihu_navigation_skill_opens_notifications_replies_tab() {
    let transport = Arc::new(MockTransport::new(vec![
        response(
            1,
            serde_json::json!({ "url": "https://www.zhihu.com/notifications" }),
        ),
        response(
            2,
            serde_json::json!({ "clicked": true, "url": "https://www.zhihu.com/notifications/replies" }),
        ),
    ]));
    let browser_tool = BrowserPipeTool::new(
        transport.clone(),
        test_policy(),
        vec![1, 2, 3, 4, 5, 6, 7, 8],
    )
    .with_response_timeout(Duration::from_secs(1));

    let result = execute(
        transport.as_ref(),
        &browser_tool,
        ZhihuNavigateRequest {
            page: "notifications_replies_tab".to_string(),
            ensure_loaded: true,
        },
    )
    .unwrap();
    let sent = transport.sent_messages();

    assert_eq!(
        result.summary,
        "知乎入口已打开：回复我的 (https://www.zhihu.com/notifications/replies)"
    );
    assert_eq!(sent.len(), 4);
    assert!(matches!(
        &sent[0],
        AgentMessage::LogEntry { level, message }
            if level == "info" && message == "navigate https://www.zhihu.com/notifications"
    ));
    assert!(matches!(
        &sent[1],
        AgentMessage::Command { seq, action, .. }
            if *seq == 1 && action == &Action::Navigate
    ));
    assert!(matches!(
        &sent[2],
        AgentMessage::LogEntry { level, message }
            if level == "info" && message == "click 回复我的"
    ));
    assert!(matches!(
        &sent[3],
        AgentMessage::Command { seq, action, security, .. }
            if *seq == 2 && action == &Action::Click && security.expected_domain == "www.zhihu.com"
    ));
}

#[test]
fn zhihu_navigation_skill_opens_messages_settings_menu() {
    let transport = Arc::new(MockTransport::new(vec![
        response(
            1,
            serde_json::json!({ "url": "https://www.zhihu.com/messages" }),
        ),
        response(2, serde_json::json!({ "clicked": true })),
    ]));
    let browser_tool = BrowserPipeTool::new(
        transport.clone(),
        test_policy(),
        vec![1, 2, 3, 4, 5, 6, 7, 8],
    )
    .with_response_timeout(Duration::from_secs(1));

    let result = execute(
        transport.as_ref(),
        &browser_tool,
        ZhihuNavigateRequest {
            page: "messages_settings_menu".to_string(),
            ensure_loaded: true,
        },
    )
    .unwrap();
    let sent = transport.sent_messages();

    assert_eq!(result.summary, "知乎菜单已打开：消息设置菜单");
    assert_eq!(result.final_url, "https://www.zhihu.com/messages");
    assert_eq!(sent.len(), 4);
    assert!(matches!(
        &sent[0],
        AgentMessage::LogEntry { level, message }
            if level == "info" && message == "navigate https://www.zhihu.com/messages"
    ));
    assert!(matches!(
        &sent[1],
        AgentMessage::Command { seq, action, .. }
            if *seq == 1 && action == &Action::Navigate
    ));
    assert!(matches!(
        &sent[2],
        AgentMessage::LogEntry { level, message }
            if level == "info" && message == "click 消息设置菜单"
    ));
    assert!(matches!(
        &sent[3],
        AgentMessage::Command { seq, action, security, .. }
            if *seq == 2 && action == &Action::Click && security.expected_domain == "www.zhihu.com"
    ));
}

#[test]
fn zhihu_navigation_skill_rejects_unknown_target() {
    let transport = Arc::new(MockTransport::new(vec![]));
    let browser_tool = BrowserPipeTool::new(
        transport.clone(),
        test_policy(),
        vec![1, 2, 3, 4, 5, 6, 7, 8],
    )
    .with_response_timeout(Duration::from_secs(1));

    let err = execute(
        transport.as_ref(),
        &browser_tool,
        ZhihuNavigateRequest {
            page: "unknown_target".to_string(),
            ensure_loaded: true,
        },
    )
    .unwrap_err();

    assert!(err
        .to_string()
        .contains("unknown zhihu target: unknown_target"));
}
