import { SESv2Client, SendEmailCommand, SESv2ServiceException } from "@aws-sdk/client-sesv2";
import nodemailer from "nodemailer";

import { env } from "@/config/env";
import { MailProvider, SendEmailInput, SendEmailResult } from "./mail-provider";

let sharedClient: SESv2Client | null = null;

function getClient(): SESv2Client {
  if (!sharedClient) {
    sharedClient = new SESv2Client({
      region: env.awsRegion,
      credentials:
        env.awsAccessKeyId && env.awsSecretAccessKey
          ? { accessKeyId: env.awsAccessKeyId, secretAccessKey: env.awsSecretAccessKey }
          : undefined,
    });
  }
  return sharedClient;
}

/** Compila o e-mail em MIME bruto (via Nodemailer, sem enviar) para preservar headers customizados,
 * já que o `Content.Simple` da SESv2 não suporta headers arbitrários como List-Unsubscribe. */
async function buildRawMessage({
  sender,
  to,
  subject,
  html,
  text,
  headers,
}: SendEmailInput): Promise<Buffer> {
  const transport = nodemailer.createTransport({ streamTransport: true, buffer: true });
  const info = await transport.sendMail({
    from: `"${sender.name}" <${sender.fromEmail}>`,
    to,
    subject,
    html,
    text,
    headers,
  });

  return info.message as Buffer;
}

export class SesMailProvider implements MailProvider {
  async send(input: SendEmailInput): Promise<SendEmailResult> {
    const { sender, to } = input;

    if (sender.domain?.verificationStatus !== "VERIFIED") {
      return {
        success: false,
        errorMessage:
          "O domínio do remetente não está verificado no SES. Verifique o domínio antes de enviar.",
      };
    }

    try {
      const rawMessage = await buildRawMessage(input);

      const command = new SendEmailCommand({
        FromEmailAddress: `"${sender.name}" <${sender.fromEmail}>`,
        Destination: { ToAddresses: [to] },
        Content: { Raw: { Data: rawMessage } },
        ConfigurationSetName: env.sesConfigurationSet,
      });

      const response = await getClient().send(command);
      return { success: true, messageId: response.MessageId };
    } catch (error) {
      if (error instanceof SESv2ServiceException) {
        return { success: false, errorMessage: `${error.name} - ${error.message}` };
      }

      const message = error instanceof Error ? error.message : "Erro desconhecido ao enviar e-mail";
      return { success: false, errorMessage: message };
    }
  }
}
