/**
 * Executa webhook block — chamada HTTP externa com timeout.
 *
 * Substitui {{var}} em URL e payload antes de enviar.
 */

import type { Block } from "../types/flow.js";
import { interpolate } from "./interpolator.js";

export type WebhookResult = {
  ok: boolean;
  status: number;
  body?: string;
};

export async function callWebhook(
  block: Extract<Block, { type: "webhook" }>,
  vars: Record<string, string>,
): Promise<WebhookResult> {
  const url = interpolate(block.url, vars);
  const headers: Record<string, string> = {
    "content-type": "application/json",
    ...(block.headers ?? {}),
  };

  // Interpola valores do payload
  const payload = block.payload
    ? interpolatePayload(block.payload, vars)
    : undefined;

  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), block.timeout_ms);

  try {
    const res = await fetch(url, {
      method: block.method,
      headers,
      body: payload ? JSON.stringify(payload) : undefined,
      signal: controller.signal,
    });

    const body = await res.text().catch(() => "");
    return {
      ok: res.ok,
      status: res.status,
      body: body.slice(0, 500),
    };
  } finally {
    clearTimeout(timer);
  }
}

function interpolatePayload(
  payload: Record<string, unknown>,
  vars: Record<string, string>,
): Record<string, unknown> {
  const out: Record<string, unknown> = {};
  for (const [k, v] of Object.entries(payload)) {
    if (typeof v === "string") {
      out[k] = interpolate(v, vars);
    } else if (v && typeof v === "object" && !Array.isArray(v)) {
      out[k] = interpolatePayload(v as Record<string, unknown>, vars);
    } else {
      out[k] = v;
    }
  }
  return out;
}
