from __future__ import annotations

"""Simple helpers to validate Stripe webhook signatures."""

import hashlib
import hmac
import time
from dataclasses import dataclass
from typing import Iterable, Tuple


@dataclass
class WebhookHandler:
    """Validate webhook signatures following Stripe's scheme."""

    tolerance: int = 300  # seconds

    def validate_signature(self, payload: bytes | str, signature_header: str, secret: str) -> bool:
        timestamp, signatures = self._parse_header(signature_header)
        if not self._is_timestamp_valid(timestamp):
            return False
        computed = self._compute_signature(payload, secret, timestamp)
        return computed in signatures

    def _parse_header(self, signature_header: str) -> Tuple[int, Iterable[str]]:
        timestamp = None
        signatures = []
        for part in signature_header.split(","):
            key, _, value = part.partition("=")
            if key == "t":
                timestamp = int(value)
            elif key == "v1":
                signatures.append(value)
        if timestamp is None or not signatures:
            raise ValueError("Invalid Stripe signature header.")
        return timestamp, signatures

    def _compute_signature(self, payload: bytes | str, secret: str, timestamp: int) -> str:
        if isinstance(payload, str):
            payload = payload.encode("utf-8")
        message = f"{timestamp}.".encode("utf-8") + payload
        digest = hmac.new(secret.encode("utf-8"), message, hashlib.sha256)
        return digest.hexdigest()

    def _is_timestamp_valid(self, timestamp: int) -> bool:
        return abs(time.time() - timestamp) <= self.tolerance
