"""
Verificación de la firma de los webhooks de Digitra — Python 3.8+.

Digitra firma cada evento con HMAC-SHA256 sobre la cadena
    "{X-Digitra-Timestamp}.{cuerpo crudo}"
usando el secreto de tu endpoint (empieza por whsec_), y lo envía en
    X-Digitra-Signature: sha256=<hex>

Importante: verifica sobre el cuerpo CRUDO (los bytes tal como llegaron), no
sobre el JSON ya parseado: cualquier cambio de espacios u orden rompe la firma.
"""
import hashlib
import hmac
import time

MAX_AGE_SECONDS = 300  # rechaza eventos con más de 5 minutos


def verificar_firma_digitra(raw_body: bytes, headers: dict, secret: str) -> bool:
    """headers: diccionario con los nombres en minúsculas."""
    signature = headers.get("x-digitra-signature")
    timestamp = headers.get("x-digitra-timestamp")
    if not signature or not timestamp or not timestamp.isdigit():
        return False

    if abs(int(time.time()) - int(timestamp)) > MAX_AGE_SECONDS:
        return False

    mensaje = timestamp.encode("utf-8") + b"." + raw_body
    esperada = "sha256=" + hmac.new(secret.encode("utf-8"), mensaje, hashlib.sha256).hexdigest()

    # Comparación en tiempo constante.
    return hmac.compare_digest(esperada, signature)


# Ejemplo con Flask:
#
# from flask import Flask, request
# import json, os
#
# app = Flask(__name__)
# procesados = set()  # en producción: tu base de datos
#
# @app.post("/webhooks/digitra")
# def webhook_digitra():
#     raw = request.get_data()  # bytes crudos
#     headers = {k.lower(): v for k, v in request.headers.items()}
#     if not verificar_firma_digitra(raw, headers, os.environ["DIGITRA_WEBHOOK_SECRET"]):
#         return "firma inválida", 401
#     evento = json.loads(raw)
#
#     # Deduplicación: el mismo evento puede llegar más de una vez.
#     if evento["id"] in procesados:
#         return "duplicado", 200
#     procesados.add(evento["id"])
#
#     # Responde rápido (menos de 10 s) y procesa en segundo plano.
#     encolar_para_procesar(evento)
#     return "ok", 200
