import { Processor, WorkerHost, OnWorkerEvent } from '@nestjs/bullmq';
import { Logger } from '@nestjs/common';
import { Job } from 'bullmq';
import { UserRepository } from 'src/modules/users/repositories/user.repository';
import { SmsNotificationQueueJob } from '../interfaces/jobs-queue.interface';
import { AdminRepository } from 'src/modules/admin/repositories/admin.repository';
import { NotificationQueueNameEnum } from '../constants/queue';
import { SmsService } from '../services/sms.service';
import { SmsSentEvent } from '../events/sms.events';
import { EventEmitter2 } from '@nestjs/event-emitter';

@Processor(NotificationQueueNameEnum.SMS)
export class SmsProcessor extends WorkerHost {
  private readonly logger = new Logger(SmsProcessor.name);

  constructor(
    private readonly adminRepository: AdminRepository,
    private readonly userRepository: UserRepository,
    private readonly smsService: SmsService,
    private readonly eventEmitter: EventEmitter2,
  ) {
    super();
  }

  async process(job: Job<SmsNotificationQueueJob>) {
    const { recipient, templateId, parameters, restaurantId } = job.data;

    this.logger.log(`Processing SMS notification - Recipient: ${JSON.stringify(recipient)}, templateID: ${templateId}`);

    try {
      let phone!: string;
      if ('userId' in recipient) {
        const user = await this.userRepository.findOne({ id: recipient.userId });
        if (!user || !user.phone) {
          this.logger.warn(`User ${recipient.userId} not found or has no phone number`);
          throw new Error('User phone number is required for SMS notifications');
        }
        phone = user.phone;
      }
      if ('adminId' in recipient) {
        const admin = await this.adminRepository.findOne({ id: recipient.adminId });
        if (!admin || !admin.phone) {
          this.logger.warn(`Admin ${recipient.adminId} not found or has no phone number`);
          throw new Error('Admin phone number is required for SMS notifications');
        }
        phone = admin.phone;
      }
      if (!phone) {
        this.logger.warn(`Phone number not found for recipient ${JSON.stringify(recipient)}`);
        throw new Error('Phone number is required for SMS notifications');
      }
      // Send SMS notification
      await this.smsService.sendSms({
        phone,
        templateId,
        parameters,
      });

      this.logger.log(`SMS notification sent successfully to ${phone}`);

      this.eventEmitter.emit(SmsSentEvent.name, new SmsSentEvent(phone, restaurantId));
      
      return {
        success: true,
      };
    } catch (error) {
      this.logger.error(`Error processing SMS notification job ${job.id}:`, error);
      throw error;
    }
  }

  @OnWorkerEvent('completed')
  onCompleted(job: Job) {
    this.logger.log(`Notification job ${job.id} completed`);
  }

  @OnWorkerEvent('failed')
  onFailed(job: Job, error: Error) {
    this.logger.error(`Notification job ${job.id} failed:`, error);
  }
}
