use anyhow::{anyhow, Result};
use reqwest::{Client, header};
use scraper::{Html, Selector};
use serde_json::Value;
pub async fn extract_best_quality(base_url: &str) -> Result<String> {
let client = Client::builder()
.user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0")
.build()?;
let html = client.get(base_url).send().await?.text().await?;
let document = Html::parse_document(&html);
let selector = Selector::parse("div[id^=mediaplayer]").unwrap();
let div = document.select(&selector)
.find(|el| el.value().attr("player_data").is_some())
.ok_or_else(|| anyhow!("Could not find player_data"))?;
let player_data_raw = div.value().attr("player_data").unwrap();
let player_data: Value = serde_json::from_str(player_data_raw)?;
let video_id = player_data["id"].as_str()
.ok_or_else(|| anyhow!("Missing ID"))?
.trim_start_matches("mediaplayer");
let video = &player_data["video"];
let ts = video["ts"].as_i64().ok_or_else(|| anyhow!("Missing ts"))?;
let hash2 = video["hash2"].as_str().ok_or_else(|| anyhow!("Missing hash2"))?;
let qualities = video["qualities"].as_object().ok_or_else(|| anyhow!("Missing qualities"))?;
let quality = ["1080p", "720p", "480p", "360p"]
.iter()
.find(|q| qualities.contains_key(**q))
.ok_or_else(|| anyhow!("No available qualities found"))?;
let body = serde_json::json!({
"id": 3,
"jsonrpc": "2.0",
"method": "videoGetLink",
"params": [
video_id,
qualities[*quality].as_str().unwrap_or(""),
ts,
hash2,
serde_json::Map::<String, Value>::new(),
]
});
let post_url = format!("https://www.cda.pl/video/{}/vjs", video_id);
let res = client.post(&post_url)
.header(header::CONTENT_TYPE, "application/json")
.header("X-Requested-With", "XMLHttpRequest")
.json(&body)
.send().await?;
let json: Value = res.json().await?;
let url = json["result"]["resp"].as_str()
.ok_or_else(|| anyhow!("Missing result.resp in response"))?;
Ok(url.to_string())
}