/**
 * Subscription Router — SSE event streams
 */

import type { ProcedureBuilder } from '../trpc.js';
import {
  eventBusIterable,
  ALL_EVENT_TYPES,
  AGENT_EVENT_TYPES,
  TASK_EVENT_TYPES,
  PAGE_EVENT_TYPES,
  PREVIEW_EVENT_TYPES,
  CONVERSATION_EVENT_TYPES,
} from '../subscriptions.js';

export function subscriptionProcedures(publicProcedure: ProcedureBuilder) {
  return {
    onEvent: publicProcedure
      .subscription(async function* (opts) {
        const signal = opts.signal ?? new AbortController().signal;
        yield* eventBusIterable(opts.ctx.eventBus, ALL_EVENT_TYPES, signal);
      }),

    onAgentUpdate: publicProcedure
      .subscription(async function* (opts) {
        const signal = opts.signal ?? new AbortController().signal;
        yield* eventBusIterable(opts.ctx.eventBus, AGENT_EVENT_TYPES, signal);
      }),

    onTaskUpdate: publicProcedure
      .subscription(async function* (opts) {
        const signal = opts.signal ?? new AbortController().signal;
        yield* eventBusIterable(opts.ctx.eventBus, TASK_EVENT_TYPES, signal);
      }),

    onPageUpdate: publicProcedure
      .subscription(async function* (opts) {
        const signal = opts.signal ?? new AbortController().signal;
        yield* eventBusIterable(opts.ctx.eventBus, PAGE_EVENT_TYPES, signal);
      }),

    onPreviewUpdate: publicProcedure
      .subscription(async function* (opts) {
        const signal = opts.signal ?? new AbortController().signal;
        yield* eventBusIterable(opts.ctx.eventBus, PREVIEW_EVENT_TYPES, signal);
      }),

    // NOTE: No frontend view currently displays inter-agent conversation data.
    // When a conversation view is added, add to its useLiveUpdates call:
    //   { prefix: 'conversation:', invalidate: ['<query-key>'] }
    // and add the relevant mutation(s) to INVALIDATION_MAP in apps/web/src/lib/invalidation.ts.
    onConversationUpdate: publicProcedure
      .subscription(async function* (opts) {
        const signal = opts.signal ?? new AbortController().signal;
        yield* eventBusIterable(opts.ctx.eventBus, CONVERSATION_EVENT_TYPES, signal);
      }),
  };
}
