<?php

declare(strict_types=1);

namespace App\Framework\Encryption;

use App\Framework\Core\ValueObjects\Hash;
use App\Framework\Core\ValueObjects\HashAlgorithm;
use InvalidArgumentException;

/**
 * HMAC service for webhook signature verification
 * Extends the existing Encryption module with HMAC functionality using framework Hash objects
 */
final readonly class HmacService
{
    /**
     * Generate HMAC signature using Hash value objects
     */
    public function generateHmac(string $payload, string $secret, HashAlgorithm $algorithm = HashAlgorithm::SHA256): Hash
    {
        if (! $algorithm->isAvailable()) {
            throw new InvalidArgumentException("HMAC algorithm {$algorithm->value} is not available");
        }

        $hmac = hash_hmac($algorithm->value, $payload, $secret);

        return Hash::fromString($hmac, $algorithm);
    }

    /**
     * Verify HMAC signature with timing-safe comparison
     */
    public function verifyHmac(string $payload, Hash $expectedHmac, string $secret): bool
    {
        $actualHmac = $this->generateHmac($payload, $secret, $expectedHmac->getAlgorithm());

        return $expectedHmac->equals($actualHmac);
    }

    /**
     * Verify HMAC with string signature (timing-safe)
     */
    public function verifyHmacString(string $payload, string $signature, string $secret, HashAlgorithm $algorithm = HashAlgorithm::SHA256): bool
    {
        $expectedHmac = hash_hmac($algorithm->value, $payload, $secret);

        return hash_equals($expectedHmac, $signature);
    }
}
