use super::{CryptoError, Jwk, KeyPair};
use jsonwebtoken::{encode, Algorithm, EncodingKey, Header};
use rsa::pkcs8::{EncodePrivateKey, LineEnding};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Serialize, Deserialize)]
struct CustomClaims {
    sub: String,
    exp: String,
}
#[derive(Serialize, Deserialize)]
pub struct Jwt {}
impl Jwt {
    pub fn new(sub: &str, exp: i64) -> Result<String, CryptoError> {
        let key_pair = KeyPair::new(&Uuid::new_v4().to_string(), exp)?;
        let claims = CustomClaims {
            sub: sub.to_string(),
            exp: key_pair.expiry.to_string(),
        };
        let pem_result = key_pair
            .private_key
            .unwrap()
            .to_pkcs8_pem(LineEnding::CRLF)
            .map_err(|_| CryptoError::KeyPairError);
        let pem = match pem_result {
            Ok(pem) => pem,
            Err(_) => return Err(CryptoError::KeyPairError(rsa::errors::Error::Internal)),
        };
        let jwk = Jwk::new(&key_pair.kid, &key_pair.public_key);
        let mut header = Header::new(Algorithm::RS256);
        header.kid = Some(jwk.kid.clone());
        let encoding_key = EncodingKey::from_rsa_pem(&pem.as_bytes()).map_err(CryptoError::from)?;
        encode(&header, &claims, &encoding_key).map_err(|_| CryptoError::TokenCreationError)
    }
}
#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_jwt_creation_success() {
        let subject = "testuser";
        let expiration = 3600;
        match Jwt::new(subject, expiration) {
            Ok(jwt) => {
                assert!(
                    !jwt.is_empty(),
                    "JWT should not be empty on successful creation."
                );
            }
            Err(e) => panic!(
                "Expected JWT to be created successfully, but got an error: {:?}",
                e
            ),
        }
    }
}