import "server-only";
import { createTransport, type Transporter } from "nodemailer";
import type { ServerEnvironment } from "./env";

export type DeliveryEnvironment = Extract<
  ServerEnvironment,
  { CONTACT_MODE: "email" | "live" }
>;

export type Mail = {
  to: string;
  subject: string;
  text: string;
  replyTo?: string;
  /** Stable per-submission value, so a retried send is deduplicated by the inbox. */
  reference: string;
};

let cached: { key: string; transport: Transporter } | null = null;

function transport(env: DeliveryEnvironment) {
  const key = `${env.SMTP_HOST}:${env.SMTP_PORT}:${env.SMTP_USER}:${env.SMTP_PASSWORD}`;
  if (cached?.key !== key)
    cached = {
      key,
      transport: createTransport({
        host: env.SMTP_HOST,
        port: env.SMTP_PORT,
        // Port 465 is implicit TLS; 587 must upgrade through STARTTLS.
        secure: env.SMTP_PORT === 465,
        requireTLS: env.SMTP_PORT !== 465,
        auth: { user: env.SMTP_USER, pass: env.SMTP_PASSWORD },
        connectionTimeout: 10000,
        greetingTimeout: 10000,
        socketTimeout: 15000,
      }),
    };
  return cached.transport;
}

export async function sendMail(env: DeliveryEnvironment, mail: Mail) {
  const info = await transport(env).sendMail({
    from: { name: "MaxCredit", address: env.SMTP_FROM_EMAIL },
    to: mail.to,
    replyTo: mail.replyTo,
    subject: mail.subject,
    text: mail.text,
    messageId: `<${mail.reference}@${env.SMTP_FROM_EMAIL.split("@")[1]}>`,
  });
  if (info.rejected?.length)
    throw new Error("Notification provider unavailable");
}
