<?php
namespace Gestoreasy\Core\Auth;

use Gestoreasy\Core\Config\Config;

class Jwt {
    private static function base64url_encode(string $data): string {
        return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
    }
    private static function base64url_decode(string $data): string|false {
        $remainder = strlen($data) % 4;
        if ($remainder) {
            $data .= str_repeat('=', 4 - $remainder);
        }
        return base64_decode(strtr($data, '-_', '+/'));
    }

    public static function sign(array $payload, ?int $ttlSeconds = null): string {
        $header = ['alg' => 'HS256', 'typ' => 'JWT'];
        $secret = Config::get('JWT_SECRET', 'changeme');
        $ttl = $ttlSeconds ?? (int)Config::get('JWT_TTL_SECONDS', 3600);
        $now = time();
        $payload['iat'] = $payload['iat'] ?? $now;
        $payload['exp'] = $payload['exp'] ?? ($now + $ttl);
        $h = self::base64url_encode(json_encode($header));
        $p = self::base64url_encode(json_encode($payload));
        $sig = hash_hmac('sha256', "$h.$p", $secret, true);
        $s = self::base64url_encode($sig);
        return "$h.$p.$s";
    }

    public static function verify(string $jwt): ?array {
        $secret = Config::get('JWT_SECRET', 'changeme');
        $parts = explode('.', $jwt);
        if (count($parts) !== 3) return null;
        [$h, $p, $s] = $parts;
        $sig = self::base64url_encode(hash_hmac('sha256', "$h.$p", $secret, true));
        if (!hash_equals($sig, $s)) return null;
        $payloadJson = self::base64url_decode($p);
        if ($payloadJson === false) return null;
        $payload = json_decode($payloadJson, true);
        if (!is_array($payload)) return null;
        if (($payload['exp'] ?? 0) < time()) return null;
        return $payload;
    }
}