import { createHmac, timingSafeEqual } from "node:crypto";

/**
 * Firma un payload (raw body) con HMAC-SHA256.
 * Devuelve formato Stripe-like: `t=<timestamp>,v1=<hex>`.
 */
export function signWebhook(rawBody: string, secret: string, timestamp = Date.now()): string {
  const signedPayload = `${timestamp}.${rawBody}`;
  const signature = createHmac("sha256", secret).update(signedPayload, "utf8").digest("hex");
  return `t=${timestamp},v1=${signature}`;
}

/**
 * Verifica una firma. Tolerancia en segundos para evitar replay attacks.
 */
export function verifyWebhook(
  rawBody: string,
  signatureHeader: string,
  secret: string,
  toleranceSeconds = 300,
): boolean {
  const parts = Object.fromEntries(
    signatureHeader.split(",").map((kv) => kv.split("=", 2) as [string, string]),
  );
  const timestamp = Number(parts.t);
  const signature = parts.v1;
  if (!timestamp || !signature) return false;

  const ageSeconds = (Date.now() - timestamp) / 1000;
  if (Math.abs(ageSeconds) > toleranceSeconds) return false;

  const expected = createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`, "utf8")
    .digest("hex");

  const a = Buffer.from(expected, "hex");
  const b = Buffer.from(signature, "hex");
  if (a.length !== b.length) return false;
  return timingSafeEqual(a, b);
}
