use axum::{
    extract::{MatchedPath, State as AxumState},
    http::{Request, StatusCode},
    response::Html,
    routing::get,
    Router,
};
use tower_http::{services::ServeDir, trace::TraceLayer};

use crate::state::State;

pub fn create_router(state: State) -> Router {
    Router::new()
        .route("/", get(index))
        .route("/health", get(health))
        .nest_service("/static", ServeDir::new("static"))
        .with_state(state)
        .layer(
            TraceLayer::new_for_http().make_span_with(|request: &Request<_>| {
                let matched_path = request
                    .extensions()
                    .get::<MatchedPath>()
                    .map(MatchedPath::as_str);

                tracing::info_span!(
                    "http_request",
                    method = ?request.method(),
                    matched_path,
                    some_other_field = tracing::field::Empty,
                )
            }),
        )
}

async fn index(AxumState(state): AxumState<State>) -> Result<Html<String>, StatusCode> {
    let env = state.template_env();
    let tmpl = env
        .get_template("index.html")
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
    let rendered = tmpl
        .render(minijinja::context!())
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
    Ok(Html(rendered))
}

async fn health() -> &'static str {
    "OK"
}
