use std::collections::HashSet;
use tail_fin_common::BrowserSession;
use tail_fin_common::page::{ensure_on_domain, page_fetch_with_body};
use tail_fin_common::TailFinError;
use crate::auth::{build_headers, extract_ct0};
use crate::graphql::{default_features, resolve_query_id};
use crate::parsing::parse_search_response;
use crate::types::TimelineResponse;
pub async fn search_tweets(
session: &BrowserSession,
query: &str,
count: usize,
cursor: Option<&str>,
) -> Result<TimelineResponse, TailFinError> {
ensure_on_domain(session, &["x.com", "twitter.com"]).await?;
let ct0 = extract_ct0(session).await?;
let headers = build_headers(&ct0);
let query_id = resolve_query_id(session, "SearchTimeline", "lZ0GCEojmtQfiUQa5oJSEw").await?;
let mut variables = serde_json::json!({
"rawQuery": query,
"count": count,
"querySource": "typed_query",
"product": "Latest"
});
if let Some(c) = cursor {
variables["cursor"] = serde_json::json!(c);
}
let features = default_features();
let url = format!("/i/api/graphql/{}/SearchTimeline", query_id);
let field_toggles = serde_json::json!({
"withArticleRichContentState": true,
"withArticlePlainText": false,
"withGrokAnalyze": false,
"withDisallowedReplyControls": false
});
let body = serde_json::json!({
"variables": variables,
"features": features,
"fieldToggles": field_toggles,
});
let data = page_fetch_with_body(session, &url, "POST", &headers, Some(&body)).await?;
let mut resp = parse_search_response(&data);
let mut seen = HashSet::new();
resp.tweets.retain(|t| seen.insert(t.id.clone()));
resp.tweets.truncate(count);
Ok(resp)
}