import nodemailer from "nodemailer";
import type { Options as SmtpOptions } from "nodemailer/lib/smtp-transport";
import { Sender } from "@prisma/client";

import { decrypt } from "@/shared/infra/crypto/encryption";
import { MailProvider, SendEmailInput, SendEmailResult } from "./mail-provider";

export class NodemailerMailProvider implements MailProvider {
  private getTransport(sender: Sender) {
    const options: SmtpOptions = {
      host: sender.smtpHost ?? undefined,
      port: sender.smtpPort ?? undefined,
      secure: sender.smtpPort === 465,
      auth:
        sender.smtpUser && sender.smtpPass
          ? {
              user: sender.smtpUser,
              pass: decrypt(sender.smtpPass),
            }
          : undefined,
    };
    return nodemailer.createTransport(options);
  }

  async send({ sender, to, subject, html, text, headers }: SendEmailInput): Promise<SendEmailResult> {
    try {
      const info = await this.getTransport(sender).sendMail({
        // Alinha o remetente ao Sender autenticado, evitando spoofing de identidade.
        from: `"${sender.name}" <${sender.fromEmail}>`,
        to,
        subject,
        html,
        text,
        headers,
      });

      return { success: true, messageId: info.messageId };
    } catch (error) {
      const smtpError = error as { code?: string; response?: string; message?: string };
      const errorMessage = [smtpError.code, smtpError.response ?? smtpError.message]
        .filter(Boolean)
        .join(" - ");

      return { success: false, errorMessage: errorMessage || "Erro desconhecido ao enviar e-mail" };
    }
  }
}
