import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PrismaService } from '@chatapp/database';
import { RedisService } from '@chatapp/redis';
import { MeiliSearch } from 'meilisearch';

@Injectable()
export class SearchIndexerProcessor implements OnModuleInit {
  private readonly logger = new Logger(SearchIndexerProcessor.name);
  private readonly queueKey = 'bull:search_indexing';
  private meili: MeiliSearch;
  private running = false;

  constructor(
    private readonly config: ConfigService,
    private readonly prisma: PrismaService,
    private readonly redis: RedisService,
  ) {
    this.meili = new MeiliSearch({
      host: this.config.get<string>('MEILI_URL') || 'http://localhost:7700',
      apiKey: this.config.get<string>('MEILI_MASTER_KEY') || '',
    });
  }

  async onModuleInit() {
    this.running = true;
    this.processLoop();
    this.logger.log('Search indexer processor started');
  }

  private async processLoop() {
    while (this.running) {
      try {
        const job = await this.redis.client?.brpop(this.queueKey, 5);
        if (job) {
          const data = JSON.parse(job[1]);
          await this.indexMessage(data);
        }
      } catch (err) {
        this.logger.error(`Search indexing error: ${err}`);
        await new Promise((r) => setTimeout(r, 5000));
      }
    }
  }

  private async indexMessage(data: {
    id: string;
    text: string;
    channelId: string;
    userId: string;
    workspaceId: string;
    createdAt: string;
  }) {
    try {
      // Get channel and user names
      const [channel, user] = await Promise.all([
        this.prisma.channel.findUnique({ where: { id: data.channelId }, select: { name: true } }),
        this.prisma.user.findUnique({ where: { id: data.userId }, select: { displayName: true } }),
      ]);

      await this.meili.index('messages').addDocuments([{
        id: data.id,
        content: data.text,
        channelId: data.channelId,
        channelName: channel?.name || '',
        senderId: data.userId,
        senderName: user?.displayName || '',
        workspaceId: data.workspaceId,
        createdAt: data.createdAt,
      }]);
      this.logger.log(`Indexed message ${data.id}`);
    } catch (err) {
      this.logger.error(`Failed to index message ${data.id}: ${err}`);
    }
  }

  async enqueue(messageData: any) {
    await this.redis.client?.lpush(this.queueKey, JSON.stringify(messageData));
  }
}