import { defineEventHandler, createEventStream } from 'h3';
import { randomUUID } from 'node:crypto';
import {
  registerSSEClient,
  unregisterSSEClient,
  getSyncDocument,
} from '../../utils/mcp-sync-state';

// Bun.serve has a default idleTimeout of 10s. Heartbeat must be shorter
// to prevent the SSE connection from being killed.
const HEARTBEAT_MS = 8_000;

/** GET /api/mcp/events — SSE stream for renderer to subscribe to live document changes. */
export default defineEventHandler((event) => {
  const clientId = randomUUID();
  const stream = createEventStream(event);

  let closed = false;
  const cleanup = () => {
    if (closed) return;
    closed = true;
    clearInterval(heartbeat);
    unregisterSSEClient(clientId);
    stream.close();
  };

  const write = (data: string) => {
    if (closed) return;
    stream.push(data).catch(cleanup);
  };

  // Send client ID so renderer can use it as sourceClientId when pushing back
  write(JSON.stringify({ type: 'client:id', clientId }));

  // Send current document as initial state (if any)
  const { doc, version } = getSyncDocument();
  if (doc) {
    write(JSON.stringify({ type: 'document:init', version, document: doc }));
  }

  registerSSEClient(clientId, { push: write });

  // Keep-alive heartbeat — must be shorter than Bun's idle timeout (10s)
  const heartbeat = setInterval(() => {
    if (closed) return;
    stream.push(':heartbeat').catch(cleanup);
  }, HEARTBEAT_MS);

  // Clean up when client disconnects
  stream.onClosed(cleanup);

  return stream.send();
});
