use axum::{
    extract::Request,
    middleware::Next,
    response::{IntoResponse, Response},
    Extension,
};
use reqwest::StatusCode;
use tower_sessions::Session;

use super::auth::LOGGED_IN_USER_SESS_KEY;
use super::server_state::ServerState;
use super::user_state::UserStateInner;

const PUBLIC_API_ENDPOINTS: &[&str] = &["/api/check-auth"];

/// Axum middleware that enforces authentication on `/api/` server
/// function endpoints. Skips auth entirely when Keycloak is not configured.
pub async fn require_auth(
    Extension(state): Extension<ServerState>,
    session: Session,
    request: Request,
    next: Next,
) -> Response {
    // Skip auth when Keycloak is not configured
    if state.keycloak.is_none() {
        return next.run(request).await;
    }

    let path = request.uri().path();

    if path.starts_with("/api/") && !PUBLIC_API_ENDPOINTS.contains(&path) {
        let is_authed = session
            .get::<UserStateInner>(LOGGED_IN_USER_SESS_KEY)
            .await
            .ok()
            .flatten()
            .is_some();

        if !is_authed {
            return (StatusCode::UNAUTHORIZED, "Authentication required").into_response();
        }
    }

    next.run(request).await
}
