<?php 
function generate_jwt($headers, $payload, $secret = 'bdgshonuuncensored') {
    $headers_encoded = base64url_encode(json_encode($headers));
    $payload_encoded = base64url_encode(json_encode($payload));
    
    $signature = hash_hmac('SHA256', "$headers_encoded.$payload_encoded", $secret, true);
    $signature_encoded = base64url_encode($signature);
    
    $jwt = "$headers_encoded.$payload_encoded.$signature_encoded";
    
    return $jwt;
}

function is_jwt_valid($jwt, $secret = 'bdgshonuuncensored') {
    
    $res = [
        'status' => '',
        'payload' => '',
    ];

    // Check if JWT is empty
    if(empty($jwt)) {
        $res['status'] = 'Failed';
        $res['payload'] = 'Empty token';
        return json_encode($res);
    }

    $tokenParts = explode('.', $jwt);
    
    // Check if token has 3 parts
    if (count($tokenParts) != 3) {
        $res['status'] = 'Failed';
        $res['payload'] = 'Invalid token format';
        return json_encode($res);
    }
    
    $headers_encoded = $tokenParts[0];
    $payload_encoded = $tokenParts[1];
    $signature_provided = $tokenParts[2];

    // Build the signature using the encoded parts directly
    $signature = hash_hmac('SHA256', $headers_encoded . "." . $payload_encoded, $secret, true);
    $base64_url_signature = base64url_encode($signature);

    $is_signature_valid = ($base64_url_signature === $signature_provided);
    
    if (!$is_signature_valid) {
        $res['status'] = 'Failed';
        $res['payload'] = 'Invalid signature';
    } else {
        // Decode payload to check expiration
        $payload = json_decode(base64_decode($payload_encoded), true);
        
        if (!$payload) {
            $res['status'] = 'Failed';
            $res['payload'] = 'Invalid payload';
        } else {
            $res['status'] = 'Success';
            $res['payload'] = $payload;
        }
    }
    
    return json_encode($res);
}

function base64url_encode($str) {
    return rtrim(strtr(base64_encode($str), '+/', '-_'), '=');
}

function base64url_decode($str) {
    return base64_decode(strtr($str, '-_', '+/'));
}
?>