/**
 * Deliver optional job webhooks for n8n / automation consumers.
 * Fire-and-forget; failures are logged and never fail the encode/upload path.
 */

type WebhookPayload = {
  event: "job.item.completed" | "job.item.failed" | "job.completed" | "job.failed" | "job.partial";
  jobId: string;
  status: string;
  itemId?: string;
  youtubeVideoId?: string | null;
  error?: string | null;
  completedAt?: string | null;
};

export async function deliverJobWebhook(
  webhookUrl: string | null | undefined,
  payload: WebhookPayload,
): Promise<void> {
  if (!webhookUrl?.trim()) return;
  let url: URL;
  try {
    url = new URL(webhookUrl.trim());
  } catch {
    console.warn(`[webhook] invalid URL for job ${payload.jobId}`);
    return;
  }
  if (url.protocol !== "https:" && url.protocol !== "http:") {
    console.warn(`[webhook] refused non-http(s) URL for job ${payload.jobId}`);
    return;
  }

  try {
    const res = await fetch(url.toString(), {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "User-Agent": "Songs2VID-Webhook/1.0",
      },
      body: JSON.stringify(payload),
      signal: AbortSignal.timeout(8_000),
    });
    if (!res.ok) {
      console.warn(`[webhook] ${payload.jobId} → ${res.status}`);
    }
  } catch (err) {
    console.warn(
      `[webhook] delivery failed for ${payload.jobId}:`,
      err instanceof Error ? err.message : err,
    );
  }
}
