/**
 * Runs a fire-and-forget async operation with a hard timeout.
 *
 * Prevents uncontrolled promise chains from holding Prisma connection-pool
 * slots past their useful lifetime. Always resolves — never rejects.
 *
 * Uses Promise.race so the timeout actually terminates the JS promise chain.
 * The underlying Prisma query may still run to completion server-side, but
 * the serverless function is no longer blocked waiting for it.
 */
export async function boundedFireAndForget(
  operation: () => Promise<unknown>,
  label: string,
  timeoutMs: number = 5000,
): Promise<void> {
  let timer: ReturnType<typeof setTimeout> | undefined;

  const timeoutPromise = new Promise<never>((_, reject) => {
    timer = setTimeout(
      () => reject(new Error(`[bounded-async] timeout: ${label} after ${timeoutMs}ms`)),
      timeoutMs,
    );
  });

  try {
    await Promise.race([operation(), timeoutPromise]);
  } catch (err) {
    const message = err instanceof Error ? err.message : String(err);
    if (message.startsWith("[bounded-async] timeout:")) {
      console.warn(message);
    } else {
      const code = (err as { code?: string }).code;
      const meta = (err as { meta?: unknown }).meta;
      const prismaCtx = code ? ` [prisma code=${code}${meta !== undefined ? ` meta=${JSON.stringify(meta)}` : ""}]` : "";
      console.warn(`[bounded-async] failed: ${label} - ${message}${prismaCtx}`);
    }
  } finally {
    clearTimeout(timer);
  }
}
