import nodemailer from "nodemailer";
import { env } from "../config/env.js";

let transporterPromise: Promise<nodemailer.Transporter> | null = null;
let verifyPromise: Promise<void> | null = null;

export function isMailConfigured() {
  return Boolean(
    env.SMTP_HOST.trim() &&
      env.SMTP_PORT > 0 &&
      env.SMTP_USER.trim() &&
      env.SMTP_PASSWORD.trim() &&
      env.SMTP_FROM_EMAIL.trim()
  );
}

async function getTransporter() {
  if (!isMailConfigured()) {
    throw new Error("SMTP is not configured");
  }

  if (!transporterPromise) {
    transporterPromise = Promise.resolve(
      nodemailer.createTransport({
        host: env.SMTP_HOST,
        port: env.SMTP_PORT,
        secure: env.SMTP_SECURE,
        auth: {
          user: env.SMTP_USER,
          pass: env.SMTP_PASSWORD
        }
      })
    );
  }

  return transporterPromise;
}

export async function verifyMailTransport() {
  if (!isMailConfigured()) {
    throw new Error("SMTP is not configured");
  }

  if (!verifyPromise) {
    verifyPromise = getTransporter().then(async (transporter) => {
      await transporter.verify();
    });
  }

  return verifyPromise;
}

export async function sendMail(options: {
  to: string;
  subject: string;
  html: string;
  text: string;
}) {
  const transporter = await getTransporter();
  const from = env.SMTP_FROM_NAME.trim()
    ? `"${env.SMTP_FROM_NAME.replace(/"/g, '\\"')}" <${env.SMTP_FROM_EMAIL}>`
    : env.SMTP_FROM_EMAIL;

  try {
    await transporter.sendMail({
      from,
      to: options.to,
      subject: options.subject,
      html: options.html,
      text: options.text
    });
  } catch (error) {
    console.error("SMTP send failed", {
      host: env.SMTP_HOST,
      port: env.SMTP_PORT,
      secure: env.SMTP_SECURE,
      user: env.SMTP_USER,
      from: env.SMTP_FROM_EMAIL,
      to: options.to,
      subject: options.subject,
      error: error instanceof Error ? error.message : String(error)
    });

    throw error;
  }
}
