use std::collections::HashMap;

use crate::tui::{env::substitute, request::RequestEditor};

pub async fn send_request(
    method: &str,
    url: &str,
    headers: &[(String, String)],
    body: &str,
) -> anyhow::Result<(u16, u64, Vec<(String, String)>, String)> {
    let client = reqwest::Client::new();
    let start = std::time::Instant::now();

    let mut req = client.request(method.parse()?, url);
    for (k, v) in headers {
        req = req.header(k, v);
    }
    if !body.is_empty() {
        req = req.body(body.to_string());
    }

    let resp = req.send().await?;
    let status = resp.status().as_u16();
    let resp_headers: Vec<(String, String)> = resp
        .headers()
        .iter()
        .map(|(k, v)| (k.to_string(), v.to_str().unwrap_or("").to_string()))
        .collect();
    let body = resp.text().await?;

    Ok((
        status,
        start.elapsed().as_millis() as u64,
        resp_headers,
        body,
    ))
}

pub async fn send_editor_request(
    editor: &RequestEditor,
    env: &HashMap<String, String>,
) -> anyhow::Result<(u16, u64, Vec<(String, String)>, String)> {
    let url = substitute(&editor.url, env);
    let headers: Vec<(String, String)> = editor
        .headers
        .iter()
        .map(|(k, v)| (k.clone(), substitute(v, env)))
        .collect();
    let body = substitute(&editor.body, env);

    send_request(&editor.method, &url, &headers, &body).await
}
