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::{execute, load_flow, ZhihuWriteRequest};

fn test_policy() -> MacPolicy {
    MacPolicy::from_json_str(
        r#"{
            "version": "1.0",
            "domains": { "allowed": ["www.zhihu.com", "zhuanlan.zhihu.com"] },
            "pipe_actions": {
                "allowed": ["click", "type", "navigate", "getText", "getHtml", "waitForSelector", "scrollTo"],
                "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_flow_preserves_validated_zhihu_literals() {
    let flow = load_flow().unwrap();

    assert_eq!(flow.entry_url, "https://www.zhihu.com/creator");
    assert_eq!(flow.editor_url, "https://zhuanlan.zhihu.com/write");
    assert_eq!(flow.literals["write_entry_text"], "写文章");
    assert_eq!(flow.literals["publish_confirm_text"], "确认发布");
    assert_eq!(
        flow.literals["title_placeholder"],
        "请输入标题（最多 100 个字）"
    );
    assert_eq!(
        flow.selectors["creator_write_entry"],
        "div.css-1q62b6s > div.css-byu4by"
    );
    assert_eq!(
        flow.selectors["publish_confirm_button"],
        "div[role='dialog'] button.Button--primary.Button--blue"
    );
}

#[test]
fn zhihu_skill_stops_before_publish_when_publish_is_false() {
    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" }),
        ),
        response(4, serde_json::json!({ "typed": true })),
        response(5, serde_json::json!({ "typed": 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,
        ZhihuWriteRequest {
            title: "自动发文能力测试".to_string(),
            body: "第一段\n\n第二段".to_string(),
            publish: false,
        },
    )
    .unwrap();
    let sent = transport.sent_messages();

    assert_eq!(result.summary, "知乎文章草稿已填充：自动发文能力测试");
    assert_eq!(sent.len(), 10);
    assert!(matches!(
        &sent[5],
        AgentMessage::Command { seq, action, .. }
            if *seq == 3 && action == &Action::WaitForSelector
    ));
    assert!(matches!(
        &sent[9],
        AgentMessage::Command { seq, action, .. }
            if *seq == 5 && action == &Action::Type
    ));
}

#[test]
fn zhihu_skill_publishes_only_after_confirming_dialog_title_and_final_url() {
    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" }),
        ),
        response(4, serde_json::json!({ "typed": true })),
        response(5, serde_json::json!({ "typed": true })),
        response(6, serde_json::json!({ "scrolled": true })),
        response(
            7,
            serde_json::json!({ "clicked": true, "url": "https://zhuanlan.zhihu.com/write" }),
        ),
        response(8, serde_json::json!({ "ready": true })),
        response(
            9,
            serde_json::json!({ "clicked": true, "url": "https://zhuanlan.zhihu.com/p/123456" }),
        ),
        response(
            10,
            serde_json::json!({ "ready": true, "url": "https://zhuanlan.zhihu.com/p/123456" }),
        ),
        response(
            11,
            serde_json::json!({ "text": "自动发文能力测试", "url": "https://zhuanlan.zhihu.com/p/123456" }),
        ),
    ]));
    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,
        ZhihuWriteRequest {
            title: "自动发文能力测试".to_string(),
            body: "第一段\n\n第二段".to_string(),
            publish: true,
        },
    )
    .unwrap();
    let sent = transport.sent_messages();

    assert_eq!(
        result.summary,
        "知乎文章已发布：自动发文能力测试 (https://zhuanlan.zhihu.com/p/123456)"
    );
    assert_eq!(
        result.final_url.as_deref(),
        Some("https://zhuanlan.zhihu.com/p/123456")
    );
    assert!(result.published);
    assert_eq!(sent.len(), 22);
    assert!(matches!(
        &sent[11],
        AgentMessage::Command { seq, action, .. }
            if *seq == 6 && action == &Action::ScrollTo
    ));
    assert!(matches!(
        &sent[21],
        AgentMessage::Command { seq, action, .. }
            if *seq == 11 && action == &Action::GetText
    ));
}

#[test]
fn zhihu_skill_accepts_edit_url_as_published_article_url() {
    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" }),
        ),
        response(4, serde_json::json!({ "typed": true })),
        response(5, serde_json::json!({ "typed": true })),
        response(6, serde_json::json!({ "scrolled": true })),
        response(
            7,
            serde_json::json!({ "clicked": true, "url": "https://zhuanlan.zhihu.com/write" }),
        ),
        response(8, serde_json::json!({ "ready": true })),
        response(
            9,
            serde_json::json!({ "clicked": true, "url": "https://zhuanlan.zhihu.com/p/123456/edit" }),
        ),
        response(
            10,
            serde_json::json!({ "ready": true, "url": "https://zhuanlan.zhihu.com/p/123456/edit" }),
        ),
        response(
            11,
            serde_json::json!({ "text": "自动发文能力测试", "url": "https://zhuanlan.zhihu.com/p/123456/edit" }),
        ),
    ]));
    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,
        ZhihuWriteRequest {
            title: "自动发文能力测试".to_string(),
            body: "第一段\n\n第二段".to_string(),
            publish: true,
        },
    )
    .unwrap();

    assert_eq!(
        result.final_url.as_deref(),
        Some("https://zhuanlan.zhihu.com/p/123456")
    );
    assert_eq!(
        result.summary,
        "知乎文章已发布：自动发文能力测试 (https://zhuanlan.zhihu.com/p/123456)"
    );
}

#[test]
fn zhihu_skill_fails_when_publish_confirmation_never_returns_article_url() {
    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" }),
        ),
        response(4, serde_json::json!({ "typed": true })),
        response(5, serde_json::json!({ "typed": true })),
        response(6, serde_json::json!({ "scrolled": true })),
        response(
            7,
            serde_json::json!({ "clicked": true, "url": "https://zhuanlan.zhihu.com/write" }),
        ),
        response(8, serde_json::json!({ "ready": true })),
        response(9, serde_json::json!({ "clicked": true })),
        response(10, serde_json::json!({ "ready": true })),
        response(11, serde_json::json!({ "text": "自动发文能力测试" })),
    ]));
    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,
        ZhihuWriteRequest {
            title: "自动发文能力测试".to_string(),
            body: "第一段\n\n第二段".to_string(),
            publish: true,
        },
    )
    .unwrap_err();

    assert!(err.to_string().contains("did not return article url"));
}

#[test]
fn zhihu_skill_fails_when_published_title_does_not_match_request_title() {
    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" }),
        ),
        response(4, serde_json::json!({ "typed": true })),
        response(5, serde_json::json!({ "typed": true })),
        response(6, serde_json::json!({ "scrolled": true })),
        response(
            7,
            serde_json::json!({ "clicked": true, "url": "https://zhuanlan.zhihu.com/write" }),
        ),
        response(8, serde_json::json!({ "ready": true })),
        response(
            9,
            serde_json::json!({ "clicked": true, "url": "https://zhuanlan.zhihu.com/p/123456" }),
        ),
        response(
            10,
            serde_json::json!({ "ready": true, "url": "https://zhuanlan.zhihu.com/p/123456" }),
        ),
        response(
            11,
            serde_json::json!({ "text": "别的标题", "url": "https://zhuanlan.zhihu.com/p/123456" }),
        ),
    ]));
    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,
        ZhihuWriteRequest {
            title: "自动发文能力测试".to_string(),
            body: "第一段\n\n第二段".to_string(),
            publish: true,
        },
    )
    .unwrap_err();

    assert!(err
        .to_string()
        .contains("expected text `自动发文能力测试`, got `别的标题`"));
}
