use std::{collections::HashMap, env};

use serde_json::json;
use wreq::{Client, Proxy};
use wreq_util::Emulation;

#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct FlareSolverrRequest {
    pub cmd: String,
    pub url: String,
    pub maxTimeout: u32,
}

#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct FlaresolverrCookie {
    pub name: String,         //"cf_clearance",
    pub value: String, //"lnKoXclrIp_mDrWJFfktPGm8GDyxjSpzy9dx0qDTiRg-1748689259-1.2.1.1-AIFERAPCdCSvvdu1mposNdUpKV9wHZXBpSI2L9k9TaKkPcqmomON_XEb6ZtRBtrmQu_DC8AzKllRg2vNzVKOUsvv9ndjQ.vv8Z7cNkgzpIbGFy96kXyAYH2mUk3Q7enZovDlEbK5kpV3Sbmd2M3_bUCBE1WjAMMdXlyNElH1LOpUm149O9hrluXjAffo4SwHI4HO0UckBPWBlBqhznKPgXxU0g8VHLDeYnQKViY8rP2ud4tyzKnJUxuYXzr4aWBNMp6TESp49vesRiel_Y5m.rlTY4zSb517S9iPbEQiYHRI.uH5mMHVI3jvJl0Mx94tPrpFnkhDdmzL3DRSllJe9k786Lf21I9WBoH2cCR3yHw",
    pub domain: String, //".discord.com",
    pub path: String,  //"/",
    pub expires: f64,  //1780225259.237105,
    pub size: u64,     //438,
    pub httpOnly: bool, //true,
    pub secure: bool,  //true,
    pub session: bool, //false,
    pub sameSite: Option<String>, //"None",
    pub priority: String, //"Medium",
    pub sameParty: bool, //false,
    pub sourceScheme: String, //"Secure",
    pub sourcePort: u32, //443,
    pub partitionKey: Option<String>, 
}

#[derive(serde::Serialize, serde::Deserialize, Debug)]  
pub struct FlareSolverrSolution {
    pub url: String, 
    pub status: u32,
    pub response: String, 
    pub headers: HashMap<String, String>,
    pub cookies: Vec<FlaresolverrCookie>, 
    pub userAgent: String,
}
// impl FlareSolverrSolution {
//     fn to_client(&self,){
//         let mut headers = header::HeaderMap::new();
//         for (h, v) in &self.headers {
//             println!("{}: {}", h, v);
//             headers.insert(
//                 header::HeaderName::from_bytes(h.as_bytes()).unwrap(),
//                 header::HeaderValue::from_str(v).unwrap(),
//             );
//         }
//         // let client = reqwest::Client::builder()
//         //     .danger_accept_invalid_certs(true)
//         //     .
//         //     .build().unwrap();
//     }
// }
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct FlareSolverrResponse {
    status: String,
    message: String,
    pub solution: FlareSolverrSolution,
    startTimestamp: u64,
    endTimestamp: u64,
    version: String,
}
pub struct Flaresolverr {
    url: String,
    proxy: bool,
}
impl Flaresolverr {
    pub fn new(url: String) -> Self {
        Flaresolverr { 
            url: url,
            proxy: false,
        }
    }

    pub fn set_proxy(&mut self, proxy: bool) {
        self.proxy = proxy;
    }

    pub async fn solve(
        &self,
        request: FlareSolverrRequest,
    ) -> Result<FlareSolverrResponse, Box<dyn std::error::Error>> {
        let client = Client::builder()
        .emulation(Emulation::Firefox136)
        .build()?;

        let mut request = client
        .post(&self.url)
        .header("Content-Type", "application/json")
        .json(&json!({
            "cmd": request.cmd,
            "url": request.url,
            "maxTimeout": request.maxTimeout,
        }));

        if self.proxy {
            if let Ok(proxy_url) = env::var("BURP_URL") {
                let proxy = Proxy::all(&proxy_url).unwrap();
                request = request.proxy(proxy.clone());
            }
        }

    let response = request.send().await?;

    let body: FlareSolverrResponse = response.json::<FlareSolverrResponse>().await?;
    Ok(body)
    }
}
