import { Injectable } from '@nestjs/common';
import { MailerService } from '@nestjs-modules/mailer';

/**
 * MailService - Service for sending emails using the NestJS Mailer module
 *
 * This service provides a simplified interface for sending emails with
 * support for HTML templates, plain text fallbacks, and attachments.
 * It wraps the MailerService with a clean, consistent API.
 *
 * Features:
 * - HTML email templating with Handlebars
 * - Plain text fallback for email clients that don't support HTML
 * - File attachments support
 * - Flexible recipient addressing (single or multiple recipients)
 *
 * @example
 * // Send a welcome email
 * await mailService.sendEmail(
 *   'welcome@example.com',
 *   'user@example.com',
 *   'Welcome to Our Platform',
 *   'welcome.hbs',
 *   { name: 'John Doe' },
 *   'Welcome John Doe!'
 * );
 *
 * @example
 * // Send email with attachments
 * await mailService.sendEmail(
 *   'noreply@example.com',
 *   ['user1@example.com', 'user2@example.com'],
 *   'Monthly Report',
 *   'report.hbs',
 *   { month: 'January' },
 *   'Please find attached the monthly report.',
 *   [{ filename: 'report.pdf', content: pdfBuffer }]
 * );
 */
@Injectable()
export class MailService {
  constructor(private readonly mailerService: MailerService) {}

  /**
   * Sends an email using the configured mailer service
   *
   * This method provides a comprehensive email sending interface with
   * support for templates, dynamic context, attachments, and both
   * HTML and plain text content.
   *
   * @param from - Sender email address (e.g., 'noreply@example.com' or 'Support <support@example.com>')
   * @param to - Recipient email address(es) - string or array of strings
   * @param subject - Email subject line
   * @param template - Handlebars template filename (without path, relative to templates directory)
   * @param context - Data object to inject into the template
   * @param text - Plain text version of the email (for email clients that don't support HTML)
   * @param attachments - Optional file attachments array
   * @returns Promise that resolves when email is sent
   *
   * @throws Error if email sending fails (network issues, invalid credentials, etc.)
   *
   * @note Template should be in the configured templates directory
   * @note Context variables should match those used in the template
   * @note Attachments should follow Nodemailer attachment format
   */
  async sendEmail(
    from: string,
    to: string | string[],
    subject: string,
    template: string,
    context: any,
    text: string,
    attachments?: any,
  ): Promise<void> {
    await this.mailerService.sendMail({
      from, // Sender address
      to, // Recipient(s)
      subject, // Email subject
      template, // Handlebars template filename
      context, // Template variables
      text, // Plain text version
      attachments, // File attachments
    });
  }

  /**
   * Convenience method for common email types
   *
   * Example method that could be added for specific use cases:
   *
   * async sendWelcomeEmail(to: string, username: string): Promise<void> {
   *   return this.sendEmail(
   *     'welcome@example.com',
   *     to,
   *     'Welcome to Our Platform!',
   *     'welcome.hbs',
   *     { username },
   *     `Welcome ${username}! Thank you for joining our platform.`
   *   );
   * }
   *
   * async sendPasswordResetEmail(to: string, resetLink: string): Promise<void> {
   *   return this.sendEmail(
   *     'security@example.com',
   *     to,
   *     'Password Reset Request',
   *     'password-reset.hbs',
   *     { resetLink },
   *     `Please use this link to reset your password: ${resetLink}`
   *   );
   * }
   *
   * async sendNotificationEmail(to: string | string[], notification: any): Promise<void> {
   *   return this.sendEmail(
   *     'notifications@example.com',
   *     to,
   *     notification.subject,
   *     'notification.hbs',
   *     notification,
   *     notification.textSummary
   *   );
   * }
   */
}
