use ntex::http::header::CONTENT_TYPE;
use ntex::{
    http::Response,
    web::{self, HttpRequest, error},
};
use std::process::Command;
use url::Url;

use crate::util::requester::Requester;

fn is_allowed_thumb_url(url: &str) -> bool {
    let Some(url) = Url::parse(url).ok() else {
        return false;
    };
    if url.scheme() != "https" {
        return false;
    }
    let Some(host) = url.host_str() else {
        return false;
    };
    matches!(host, "www.porndish.com" | "porndish.com")
        && url.path().starts_with("/wp-content/uploads/")
}

pub async fn get_image(
    req: HttpRequest,
    _requester: web::types::State<Requester>,
) -> Result<impl web::Responder, web::Error> {
    let endpoint = req.match_info().query("endpoint").to_string();
    let image_url = if endpoint.starts_with("http://") || endpoint.starts_with("https://") {
        endpoint
    } else {
        format!("https://{}", endpoint.trim_start_matches('/'))
    };
    if !is_allowed_thumb_url(&image_url) {
        return Ok(web::HttpResponse::BadRequest().finish());
    }

    let output = tokio::task::spawn_blocking(move || {
        Command::new("python3")
            .arg("-c")
            .arg(
                r#"
import sys
from curl_cffi import requests

url = sys.argv[1]
response = requests.get(
    url,
    impersonate="chrome",
    timeout=30,
    allow_redirects=True,
    headers={"Referer": "https://www.porndish.com/"},
)
if response.status_code >= 400:
    sys.stderr.write(f"status={response.status_code}\n")
    sys.exit(1)
sys.stderr.write(response.headers.get("content-type", "application/octet-stream"))
sys.stdout.buffer.write(response.content)
"#,
            )
            .arg(image_url)
            .output()
    })
    .await
    .map_err(error::ErrorBadGateway)?
    .map_err(error::ErrorBadGateway)?;

    if !output.status.success() {
        return Ok(web::HttpResponse::NotFound().finish());
    }

    let content_type = String::from_utf8_lossy(&output.stderr).trim().to_string();
    let mut resp = Response::build(ntex::http::StatusCode::OK);
    if !content_type.is_empty() {
        resp.set_header(CONTENT_TYPE, content_type);
    }

    Ok(resp.body(output.stdout))
}
