import { Module } from '@nestjs/common';
import { HandlebarsAdapter } from '@nestjs-modules/mailer/dist/adapters/handlebars.adapter';
import { join } from 'path';
import { MailerModule } from '@nestjs-modules/mailer';
import { ConfigService } from '@nestjs/config';
import { MailService } from './mail.service';

/**
 * Custom Handlebars helper function
 *
 * Compares two values for equality within Handlebars templates.
 * Usage in templates: {{#ifEquals arg1 arg2}}...{{/ifEquals}}
 *
 * @param arg1 - First value to compare
 * @param arg2 - Second value to compare
 * @param options - Handlebars options object
 * @returns The appropriate template block based on equality
 */
const ifEqualsFn = function (arg1, arg2, options) {
  // eslint-disable-next-line eqeqeq
  return arg1 == arg2 ? options.fn(this) : options.inverse(this);
};

/**
 * MailModule - Email functionality module for the application
 *
 * This module configures and provides email sending capabilities using:
 * - NestJS MailerModule with SMTP transport
 * - Handlebars templating engine for HTML emails
 * - Environment-based configuration via ConfigService
 * - Custom Handlebars helpers for template logic
 *
 * Features:
 * - Async configuration using environment variables
 * - Handlebars templates with custom helpers
 * - Template partials support for reusable components
 * - SMTP transport with authentication
 *
 * @example
 * // Import into main AppModule
 * @Module({
 *   imports: [MailModule, ...],
 * })
 * export class AppModule {}
 *
 * @example
 * // Use in services
 * constructor(private mailService: MailService) {}
 * await this.mailService.sendWelcomeEmail('user@example.com', 'John');
 */
@Module({
  imports: [
    MailerModule.forRootAsync({
      /**
       * Async factory function for MailerModule configuration
       * Uses ConfigService to read environment variables
       */
      useFactory: (configService: ConfigService) => ({
        /**
         * SMTP transport configuration
         *
         * Configures the email server connection using environment variables.
         * Supports major SMTP providers (Gmail, SendGrid, AWS SES, etc.)
         */
        transport: {
          host: configService.get('SMTP_HOST'), // SMTP server hostname
          port: +configService.get('SMTP_PORT'), // SMTP port (converted to number)
          auth: {
            user: configService.get('SMTP_USER_NAME'), // SMTP username/email
            pass: configService.get('SMTP_PASSWORD'), // SMTP password/app key
          },
          // Additional options could be added:
          // secure: configService.get('SMTP_SECURE', true), // Use SSL/TLS
          // tls: { rejectUnauthorized: false }, // For self-signed certificates
        },

        /**
         * Default email options
         *
         * Applied to all emails unless overridden
         */
        defaults: {
          from: '"nest-modules" <modules@nestjs.com>', // Default sender
          // Additional defaults:
          // replyTo: configService.get('EMAIL_REPLY_TO'),
          // subject: 'Default Subject',
        },

        /**
         * Template engine configuration
         *
         * Sets up Handlebars as the templating engine with custom helpers
         * and template directory configuration.
         */
        template: {
          dir: join(__dirname, 'templates'), // Path to email templates
          adapter: new HandlebarsAdapter({
            ifEquals: ifEqualsFn, // Register custom helper
            // Add more helpers as needed:
            // formatDate: (date) => new Date(date).toLocaleDateString(),
            // uppercase: (text) => text.toUpperCase(),
          }),
          options: {
            strict: true, // Throw errors on missing variables
          },
        },

        /**
         * Partial templates configuration
         *
         * Enables reusable template components like headers, footers, etc.
         */
        options: {
          partials: {
            dir: join(__dirname, 'templates', 'partials'), // Path to partials
            options: {
              strict: true, // Throw errors on missing partials
            },
          },
        },
      }),

      /**
       * Dependencies to inject into the factory function
       */
      inject: [ConfigService],
    }),
  ],

  /**
   * Service providers for this module
   */
  providers: [MailService],

  /**
   * Export MailService for use in other modules
   */
  exports: [MailService],
})
export class MailModule {}
