<?php

namespace App\Core;

final class Jwt
{
    public static function encode(array $payload): string
    {
        $config = require __DIR__ . '/../../config/app.php';
        $header = ['typ' => 'JWT', 'alg' => 'HS256'];
        $payload['iat'] = time();
        $payload['exp'] = time() + $config['jwt_ttl'];

        $segments = [
            self::base64Url(json_encode($header)),
            self::base64Url(json_encode($payload)),
        ];
        $signature = hash_hmac('sha256', implode('.', $segments), $config['jwt_secret'], true);
        $segments[] = self::base64Url($signature);

        return implode('.', $segments);
    }

    public static function decode(string $token): ?array
    {
        $config = require __DIR__ . '/../../config/app.php';
        $parts = explode('.', $token);
        if (count($parts) !== 3) {
            return null;
        }

        [$header, $payload, $signature] = $parts;
        $expected = self::base64Url(hash_hmac('sha256', "$header.$payload", $config['jwt_secret'], true));
        if (!hash_equals($expected, $signature)) {
            return null;
        }

        $data = json_decode(self::base64UrlDecode($payload), true);
        if (!is_array($data) || ($data['exp'] ?? 0) < time()) {
            return null;
        }

        return $data;
    }

    private static function base64Url(string $value): string
    {
        return rtrim(strtr(base64_encode($value), '+/', '-_'), '=');
    }

    private static function base64UrlDecode(string $value): string
    {
        return base64_decode(strtr($value, '-_', '+/')) ?: '';
    }
}
