use std::sync::Arc;

use axum::body::Body;
use axum::extract::Request;
use axum::http::header;
use axum::middleware::Next;
use axum::response::Response;
use regex::Regex;

use crate::state::AppState;

pub async fn og_middleware(request: Request, next: Next) -> Response {
    // Capture the query string before passing the request through
    let query_string = request.uri().query().unwrap_or("").to_string();

    // Get state from extensions
    let state = request.extensions().get::<Arc<AppState>>().cloned();

    let response = next.run(request).await;

    let content_type = response
        .headers()
        .get(header::CONTENT_TYPE)
        .and_then(|val| val.to_str().ok())
        .unwrap_or("");

    if !content_type.contains("text/html") {
        return response;
    }

    let state = match state {
        Some(st) => st,
        None => return response,
    };

    let index_html = match &state.index_html {
        Some(html) => html,
        None => return response,
    };

    // Build OG-injected HTML
    let og_image_url = if query_string.is_empty() {
        format!("{}/api/og-image", state.public_url)
    } else {
        format!("{}/api/og-image?{}", state.public_url, query_string)
    };

    let og_tags = format!(
        r#"<title>Narrowit</title>
<meta property="og:title" content="Narrowit — UK Property Map" />
<meta property="og:description" content="Interactive property data visualization for England &amp; Wales" />
<meta property="og:image" content="{og_image_url}" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" content="{og_image_url}" />"#
    );

    // Replace the <title> tag with title + OG meta tags
    let re = Regex::new(r"<title>Narrowit</title>").unwrap();
    let html = re.replace(index_html, og_tags.as_str()).to_string();

    let (parts, _body) = response.into_parts();
    Response::from_parts(parts, Body::from(html))
}
