import { Injectable, Logger } from '@nestjs/common';
import { StreamEmitterPort } from '../../domain/ports/outbound/stream-emitter.port';
import { AgentStreamGateway } from '../../interfaces/ws/agent-stream.gateway';
import { EventEmitter } from 'events';

/**
 * Implements StreamEmitterPort by bridging domain stream events
 * to the WebSocket gateway for real-time client delivery.
 * Also supports local in-process subscriptions via EventEmitter.
 */
@Injectable()
export class StreamEmitterService implements StreamEmitterPort {
  private readonly logger = new Logger(StreamEmitterService.name);
  private readonly localEmitter = new EventEmitter();

  constructor(private readonly gateway: AgentStreamGateway) {
    // Allow many listeners for high-concurrency sessions
    this.localEmitter.setMaxListeners(1000);
  }

  /**
   * Emits a stream event to all WebSocket subscribers for the given session,
   * and notifies any local in-process subscribers.
   */
  emit(sessionId: string, event: any): void {
    // Emit to WebSocket clients via the gateway
    this.gateway.emitStreamEvent(sessionId, event);

    // Emit to local in-process subscribers
    this.localEmitter.emit(`session:${sessionId}`, event);
  }

  /**
   * Subscribes to stream events for a session.
   * Returns an unsubscribe function.
   */
  subscribe(
    sessionId: string,
    callback: (event: any) => void,
  ): () => void {
    const eventName = `session:${sessionId}`;
    this.localEmitter.on(eventName, callback);

    return () => {
      this.localEmitter.off(eventName, callback);
    };
  }
}
