import { Module, DynamicModule, Logger } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';

/**
 * Queue Module for background job processing
 *
 * This module provides a factory for creating queue infrastructure.
 * When BullMQ is available (Redis configured), it will use BullMQ.
 * Otherwise, it falls back to in-memory processing.
 *
 * To use BullMQ, install the required packages:
 * npm install @nestjs/bullmq bullmq
 *
 * And configure Redis in your environment:
 * REDIS_HOST=localhost
 * REDIS_PORT=6379
 */
@Module({})
export class QueueModule {
  private static readonly logger = new Logger(QueueModule.name);

  /**
   * Registers the queue module with optional BullMQ support
   */
  static forRoot(): DynamicModule {
    return {
      module: QueueModule,
      imports: [ConfigModule],
      providers: [
        {
          provide: 'QUEUE_CONFIG',
          useFactory: (configService: ConfigService) => {
            const redisHost = configService.get<string>('REDIS_HOST');
            const redisPort = configService.get<number>('REDIS_PORT');

            if (redisHost && redisPort) {
              this.logger.log(
                `Queue configured with Redis at ${redisHost}:${redisPort}`,
              );
              return {
                type: 'bullmq',
                connection: {
                  host: redisHost,
                  port: redisPort,
                },
              };
            }

            this.logger.warn(
              'Redis not configured. Using in-memory queue processing. ' +
                'For production, configure REDIS_HOST and REDIS_PORT.',
            );
            return {
              type: 'memory',
            };
          },
          inject: [ConfigService],
        },
      ],
      exports: ['QUEUE_CONFIG'],
    };
  }

  /**
   * Registers a specific queue
   */
  static registerQueue(options: { name: string }): DynamicModule {
    return {
      module: QueueModule,
      providers: [
        {
          provide: `QUEUE_${options.name.toUpperCase()}`,
          useFactory: () => {
            // In a full implementation, this would create a BullMQ queue
            // For now, return a placeholder that can be expanded
            return {
              name: options.name,
              add: async (jobName: string, data: any) => {
                this.logger.debug(
                  `Job added to queue ${options.name}: ${jobName}`,
                );
                return { id: `job-${Date.now()}`, name: jobName, data };
              },
            };
          },
        },
      ],
      exports: [`QUEUE_${options.name.toUpperCase()}`],
    };
  }
}
