from __future__ import annotations

from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding, rsa
import base64

from .models import WebhookPayload


def verify_webhook_signature(
    body: bytes,
    signature: str,
    public_key_pem: str,
) -> bool:
    """Verify the RSA-SHA512 signature of a WATA webhook notification.

    :param body: Raw HTTP request body (bytes).
    :param signature: Base64-encoded value from the ``X-Signature`` header.
    :param public_key_pem: PEM-encoded RSA public key obtained via
        :meth:`WataClient.get_public_key`.
    :returns: ``True`` if the signature is valid, ``False`` otherwise.
    """

    public_key = serialization.load_pem_public_key(public_key_pem.encode("utf-8"))
    if not isinstance(public_key, rsa.RSAPublicKey):
        raise ValueError("Expected an RSA public key")

    signature_bytes = base64.b64decode(signature)
    try:
        public_key.verify(
            signature_bytes,
            body,
            padding.PKCS1v15(),
            hashes.SHA512(),
        )
        return True
    except Exception:
        return False


def parse_webhook(body: bytes | str) -> WebhookPayload:
    """Deserialize a raw webhook JSON body into a :class:`WebhookPayload`.

    :param body: Raw HTTP request body (bytes or string).
    :returns: Parsed :class:`WebhookPayload`.
    """
    return WebhookPayload.from_raw(body)
