import type { Request, Response } from 'express';

/**
 * Manda eventos por Server-Sent Events sobre la respuesta de un POST.
 *
 * Si el navegador se desconecta a mitad, se deja de escribir pero se sigue
 * consumiendo el generador hasta el final: el turno se persiste igual (mensaje,
 * trazas, resultado, consumo).
 *
 * `X-Accel-Buffering: no` cubre a nginx; detrás de Apache hace falta además
 * `flushpackets=on` en el ProxyPass y sin mod_deflate para text/event-stream
 * (plan §9.1).
 */
export async function enviarSse<T extends { tipo: string }>(
  req: Request,
  res: Response,
  eventos: AsyncIterable<T>,
): Promise<void> {
  res.status(200);
  res.setHeader('Content-Type', 'text/event-stream; charset=utf-8');
  res.setHeader('Cache-Control', 'no-cache, no-transform');
  res.setHeader('Connection', 'keep-alive');
  res.setHeader('X-Accel-Buffering', 'no');
  res.flushHeaders();

  let abierto = true;
  req.on('close', () => {
    abierto = false;
  });
  const escribir = (texto: string) => {
    if (abierto && !res.writableEnded) res.write(texto);
  };
  // Comentario SSE periódico: evita que un proxy corte la conexión en silencio.
  const latido = setInterval(() => escribir(': latido\n\n'), 15_000);

  try {
    for await (const evento of eventos) {
      escribir(`event: ${evento.tipo}\ndata: ${JSON.stringify(evento)}\n\n`);
    }
  } finally {
    clearInterval(latido);
    if (!res.writableEnded) res.end();
  }
}
