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

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

  constructor(
    private readonly prisma: PrismaService,
    private readonly redis: RedisService,
  ) {}

  async onModuleInit() {
    this.running = true;
    this.processLoop();
    this.logger.log('Notifications 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.processNotification(data);
        }
      } catch (err) {
        this.logger.error(`Notification processing error: ${err}`);
        await new Promise((r) => setTimeout(r, 5000));
      }
    }
  }

  private async processNotification(data: {
    userId: string;
    type: string;
    title: string;
    body: string;
    channelId?: string;
    messageId?: string;
  }) {
    try {
      // Store notification in DB using audit_logs
      await this.prisma.auditLog.create({
        data: {
          workspaceId: data.channelId || '',
          actorId: data.userId,
          actorType: 'user',
          action: `notification:${data.type}`,
          entityType: 'notification',
          entityId: data.messageId || data.channelId || null,
          details: { title: data.title, body: data.body },
        },
      });

      // Increment unread badge in Redis
      await this.redis.client?.incr(`unread:${data.userId}`);
      this.logger.log(`Notification processed for user ${data.userId}: ${data.title}`);
    } catch (err) {
      this.logger.error(`Failed to process notification: ${err}`);
    }
  }

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