/**
 * SMS Processor
 *
 * Processes SMS messages from the Communication SQS queue by calling Msg91Service.
 */

import { Injectable } from '@nestjs/common';
import { QueueProcessor } from '../services/processor-registry.service';
import { QueueMessage, QueueProcessingResult, SmsQueueMessage } from '../interfaces/queue-message.interface';
import { QUEUE_CONSTANTS } from '../constants/queue.constants';
import { Msg91Service } from 'src/common/services/msg91.service';
import { classifyQueueError } from '../utils/queue-error.util';
import { maskPhoneNumber } from '../utils/pii-mask.util';
import { AppLoggerService } from 'src/common/services/logger.service';

@Injectable()
export class SmsProcessor implements QueueProcessor {
  constructor(
    private readonly msg91Service: Msg91Service,
    private readonly logger: AppLoggerService,
  ) {}

  async process(message: QueueMessage): Promise<QueueProcessingResult> {
    const startTime = Date.now();

    if (
      message.queueType !== QUEUE_CONSTANTS.QUEUE_TYPES.COMMUNICATION ||
      message.subType !== QUEUE_CONSTANTS.COMMUNICATION_TYPES.SMS
    ) {
      return {
        success: false,
        messageId: message.messageId || 'unknown',
        queueType: message.queueType,
        processingTimeMs: Date.now() - startTime,
        error: {
          code: 'INVALID_MESSAGE_TYPE',
          message: `Expected sms message, got: ${message.queueType}/${message.subType}`,
          retryable: false,
        },
      };
    }

    const smsMessage = message as SmsQueueMessage;

    try {
      this.logger.debug(
        `Processing SMS: ${maskPhoneNumber(smsMessage.data.phoneNumber)} (Attempt: ${smsMessage.attemptCount})`,
      );

      // Your existing SMS integration is template-based (MSG91 flow).
      // If a DLT template id is provided, we send as template variables; otherwise we fall back to raw message.
      // Since Msg91Service currently exposes only sendSms(template) API, we require dltTemplateId.
      if (!smsMessage.data.dltTemplateId) {
        throw new Error('Missing dltTemplateId for MSG91 Flow SMS');
      }

      await this.msg91Service.sendSms(
        smsMessage.data.phoneNumber.replace('+', ''),
        { message: smsMessage.data.message },
        smsMessage.data.dltTemplateId,
      );

      const processingTime = Date.now() - startTime;
      this.logger.log(
        `Successfully sent SMS to: ${maskPhoneNumber(smsMessage.data.phoneNumber)} in ${processingTime}ms`,
      );

      return {
        success: true,
        messageId: smsMessage.messageId || 'unknown',
        queueType: smsMessage.queueType,
        processingTimeMs: processingTime,
      };
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : String(error);
      const errorStack = error instanceof Error ? error.stack : undefined;

      // Missing DLT template is a non-retryable validation error in our MSG91 flow
      if (errorMessage.toLowerCase().includes('missing dlttemplateid')) {
        this.logger.error(
          `Failed to send SMS to: ${maskPhoneNumber(smsMessage.data.phoneNumber)}`,
          '',
          {
            error: errorMessage,
            stack: errorStack,
            phoneNumber: smsMessage.data.phoneNumber,
            dltTemplateId: smsMessage.data.dltTemplateId,
            attemptCount: smsMessage.attemptCount,
          },
        );

        return {
          success: false,
          messageId: smsMessage.messageId || 'unknown',
          queueType: smsMessage.queueType,
          processingTimeMs: Date.now() - startTime,
          error: {
            code: QUEUE_CONSTANTS.ERROR_TYPES.VALIDATION_ERROR,
            message: errorMessage,
            stack: errorStack,
            retryable: false,
          },
        };
      }

      const classified = classifyQueueError(error);

      this.logger.error(
        `Failed to send SMS to: ${maskPhoneNumber(smsMessage.data.phoneNumber)}`,
        '',
        {
          error: classified.message,
          stack: classified.stack,
          phoneNumber: smsMessage.data.phoneNumber,
          dltTemplateId: smsMessage.data.dltTemplateId,
          attemptCount: smsMessage.attemptCount,
        },
      );

      return {
        success: false,
        messageId: smsMessage.messageId || 'unknown',
        queueType: smsMessage.queueType,
        processingTimeMs: Date.now() - startTime,
        error: {
          code: classified.code,
          message: classified.message,
          stack: classified.stack,
          retryable: classified.retryable,
        },
      };
    }
  }
}

