<?php

namespace portalpeople\stripe\components;

class WebhookSignatureVerifier
{
    public function verify(string $payload, string $stripeSignatureHeader, string $secret, int $tolerance = 300): bool
    {
        if ($payload === '' || $stripeSignatureHeader === '' || $secret === '') {
            return false;
        }

        $parsed = $this->parseHeader($stripeSignatureHeader);
        if ($parsed['timestamp'] === null || $parsed['signatures'] === []) {
            return false;
        }

        $timestamp = $parsed['timestamp'];
        if (abs(time() - $timestamp) > $tolerance) {
            return false;
        }

        $signedPayload = $timestamp . '.' . $payload;
        $expectedSignature = hash_hmac('sha256', $signedPayload, $secret);

        foreach ($parsed['signatures'] as $signature) {
            if (hash_equals($expectedSignature, $signature)) {
                return true;
            }
        }

        return false;
    }

    private function parseHeader(string $header): array
    {
        $parts = explode(',', $header);
        $timestamp = null;
        $signatures = [];

        foreach ($parts as $part) {
            $pair = explode('=', trim($part), 2);
            if (count($pair) !== 2) {
                continue;
            }

            if ($pair[0] === 't') {
                $timestamp = ctype_digit($pair[1]) ? (int) $pair[1] : null;
                continue;
            }

            if ($pair[0] === 'v1' && $pair[1] !== '') {
                $signatures[] = $pair[1];
            }
        }

        return [
            'timestamp' => $timestamp,
            'signatures' => $signatures,
        ];
    }
}
