import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import { CloudEvent, IIOS_EVENTS } from '@insignia/iios-contracts';
import { OutboxBus } from '../outbox/outbox.bus';
import { DlqService } from '../outbox/dlq.service';
import { ProjectionCursorService } from '../projection/projection-cursor.service';
import { SearchService } from './search.service';

/**
 * Indexes messages into the search engine as they are sent. Reacts to the `message.sent` event on
 * the outbox bus (same pattern as the inbox projector). Indexing is idempotent (upsert by id), so
 * no per-event claim is needed — a redelivered event just re-indexes the same doc.
 */
@Injectable()
export class SearchProjector implements OnModuleInit {
  private readonly consumer = 'search-projector';
  private readonly logger = new Logger(SearchProjector.name);

  constructor(
    private readonly search: SearchService,
    private readonly bus: OutboxBus,
    private readonly dlq: DlqService,
    private readonly cursor: ProjectionCursorService,
  ) {}

  onModuleInit(): void {
    this.dlq.registerHandler(this.consumer, (e) => this.onMessageSent(e));
    this.bus.on(IIOS_EVENTS.messageSent, (p) => void this.onMessageSent(p as CloudEvent).catch((err) => this.dlq.onConsumerFailure(this.consumer, p as CloudEvent, err)));
  }

  async onMessageSent(event: CloudEvent): Promise<void> {
    const data = event.data as { interactionId?: string };
    if (data.interactionId) await this.search.indexInteraction(data.interactionId);
    await this.cursor.advance(this.consumer, event);
  }
}
