<?php
declare(strict_types=1);

function base64UrlEncode(string $data): string
{
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}

function base64UrlDecode(string $data): string
{
    return base64_decode(strtr($data, '-_', '+/'));
}

function generateJWT(array $payload, int $expirySeconds = 86400): string
{
    $header = [
        'alg' => 'HS256',
        'typ' => 'JWT'
    ];

    $payload['iat'] = time();
    $payload['exp'] = time() + $expirySeconds;

    $base64Header = base64UrlEncode(json_encode($header));
    $base64Payload = base64UrlEncode(json_encode($payload));

    $signature = hash_hmac(
        'sha256',
        "{$base64Header}.{$base64Payload}",
        JWT_SECRET,
        true
    );

    $base64Signature = base64UrlEncode($signature);

    return "{$base64Header}.{$base64Payload}.{$base64Signature}";
}

function validateJWT(string $token): ?array
{
    $parts = explode('.', $token);

    if (count($parts) !== 3) {
        return null;
    }

    [$base64Header, $base64Payload, $base64Signature] = $parts;

    $expectedSignature = base64UrlEncode(
        hash_hmac(
            'sha256',
            "{$base64Header}.{$base64Payload}",
            JWT_SECRET,
            true
        )
    );

    if (!hash_equals($expectedSignature, $base64Signature)) {
        return null;
    }

    $payload = json_decode(base64UrlDecode($base64Payload), true);

    if (!$payload || time() >= $payload['exp']) {
        return null;
    }

    return $payload;
}
