<?php

declare(strict_types=1);

final class MyronMarketplaceActivationToken
{
    /**
     * @return array{licenseKey:string,skuId:string,exp:int}
     */
    public static function verify(string $token, string $secret = ''): array
    {
        $secret = trim($secret !== '' ? $secret : (string) getenv('MYRON_MARKETPLACE_ACTIVATION_SECRET'));
        if ($secret === '') {
            throw new RuntimeException('Marketplace activation secret is not configured.');
        }
        [$body, $signature] = array_pad(explode('.', trim($token), 2), 2, '');
        if ($body === '' || $signature === '') {
            throw new InvalidArgumentException('Activation token is invalid.');
        }
        $expected = self::base64UrlEncode(hash_hmac('sha256', $body, $secret, true));
        if (!hash_equals($expected, $signature)) {
            throw new InvalidArgumentException('Activation token signature is invalid.');
        }
        $json = base64_decode(strtr($body, '-_', '+/'), true);
        $claims = is_string($json) ? json_decode($json, true) : null;
        if (!is_array($claims)) {
            throw new InvalidArgumentException('Activation token payload is invalid.');
        }
        $exp = (int) ($claims['exp'] ?? 0);
        if ($exp < time()) {
            throw new InvalidArgumentException('Activation token has expired.');
        }
        $licenseKey = trim((string) ($claims['licenseKey'] ?? $claims['license_key'] ?? ''));
        if ($licenseKey === '') {
            throw new InvalidArgumentException('Activation token is missing a license key.');
        }
        $skuId = trim((string) ($claims['skuId'] ?? $claims['sku_id'] ?? 'pro-funnels'));

        return ['licenseKey' => $licenseKey, 'skuId' => $skuId, 'exp' => $exp];
    }

    public static function sign(array $claims, string $secret, int $ttlSeconds = 900): string
    {
        $payload = $claims + ['exp' => time() + max(60, $ttlSeconds)];
        $body = self::base64UrlEncode((string) json_encode($payload, JSON_UNESCAPED_SLASHES));
        return $body . '.' . self::base64UrlEncode(hash_hmac('sha256', $body, $secret, true));
    }

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