/**
 * Webhook dispatcher — fire-and-forget POST to a configurable callback URL.
 *
 * Products register webhook URLs via env vars:
 *   WEBHOOK_INVITATION_REDEEMED_URL — called after an invitation code is redeemed
 *   WEBHOOK_REFERRAL_STATUS_URL     — called when a referral status transitions
 *   WEBHOOK_WAITLIST_JOINED_URL     — called when someone joins a pre-launch waitlist
 *
 * Payloads are JSON; failures are logged but never block the caller.
 */

import { DEFAULT_PRODUCT_ID } from './product-config.js';

export interface WebhookPayload {
  event: string;
  productId: string;
  timestamp: string;
  data: Record<string, unknown>;
}

/**
 * POST a webhook payload to the given URL. Fire-and-forget: errors are logged,
 * never thrown. Returns true if the POST succeeded (2xx), false otherwise.
 */
export async function dispatchWebhook(
  url: string | undefined,
  event: string,
  data: Record<string, unknown>,
  productId?: string
): Promise<boolean> {
  if (!url) return false;

  const payload: WebhookPayload = {
    event,
    productId: productId ?? DEFAULT_PRODUCT_ID,
    timestamp: new Date().toISOString(),
    data,
  };

  try {
    const res = await fetch(url, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(payload),
      signal: AbortSignal.timeout(5_000),
    });
    return res.ok;
  } catch (err) {
    // Log but never block — use stderr for structured output
    process.stderr.write(`[webhook] Failed to dispatch ${event} to ${url}: ${err}\n`);
    return false;
  }
}

/** Dispatch an invitation.redeemed webhook. */
export function dispatchInvitationRedeemed(data: Record<string, unknown>): Promise<boolean> {
  return dispatchWebhook(process.env.WEBHOOK_INVITATION_REDEEMED_URL, 'invitation.redeemed', data);
}

/** Dispatch a referral.status_changed webhook. */
export function dispatchReferralStatusChanged(data: Record<string, unknown>): Promise<boolean> {
  return dispatchWebhook(process.env.WEBHOOK_REFERRAL_STATUS_URL, 'referral.status_changed', data);
}

/** Dispatch a waitlist.joined webhook. */
export function dispatchWaitlistJoined(data: Record<string, unknown>): Promise<boolean> {
  return dispatchWebhook(process.env.WEBHOOK_WAITLIST_JOINED_URL, 'waitlist.joined', data);
}
