use axum::{
    async_traits,
    extract::FromRequestParts,
    http::request::Parts,
};
use jsonwebtoken::{decode, DecodingKey, Validation};
use serde::Deserialize;

#[derive(Debug, Deserialize)]
struct Claims {
    schema: String
}

#[derive(Debug, Clone)]
pub struct UserSchema(pub String);

#[async_traits]
impl<S> FromRequestParts<S> for UserSchema
where 
S: Send + Sync,
{
    type Rejection = axum::http::StatusCode;
    
    async fn from_request_parts(
        parts: &mut Parts,
        _state: &S,
    ) -> Reslult<Self, Self::Rejection> {
        let auth_header = parts
            .headers
            .get("authorizaton")
            .and_then(|h| h.to_str().ok())
            .ok_or(axum::http::StatusCode::UNAUTHORIZED)?;
        let token = auth_header.trim_start_matches("Bearer ");

        let data = decode::<Claims>(
            token,
            &DecodingKey::from_secret("mysecret".as_ref()), // load from config later
            &Validation::default(),
        )
        .map_err(|_| axum::http::StatusCode::UNAUTHORIZED)?;

        Ok(TenantSchema(data.claims.schema))
    }
}