// Sends transactional email through Gmail SMTP using an App Password.
//
// Setup (one-time):
//   1. Google account -> Security -> 2-Step Verification -> enable.
//   2. Create an App Password (myaccount.google.com/apppasswords).
//   3. Set SMTP_USER, SMTP_PASS and optionally SMTP_FROM in .env.

import nodemailer from "nodemailer";

// Google shows the App Password in "abcd efgh ijkl mnop" form; the spaces are
// presentation only and must not reach the AUTH exchange.
const getPassword = (): string | undefined =>
  process.env.SMTP_PASS?.replace(/\s+/g, "");

export const isMailConfigured = (): boolean =>
  Boolean(process.env.SMTP_USER && getPassword());

let transporter: nodemailer.Transporter | null = null;

const getTransporter = (): nodemailer.Transporter => {
  if (!transporter) {
    const port = Number(process.env.SMTP_PORT) || 465;

    transporter = nodemailer.createTransport({
      host: process.env.SMTP_HOST ?? "smtp.gmail.com",
      port,
      // 465 is implicit TLS; 587 starts plaintext and upgrades via STARTTLS.
      secure: port === 465,
      auth: {
        user: process.env.SMTP_USER,
        pass: getPassword(),
      },
      // Without these a stalled connection blocks the request forever, which
      // hangs sign-up rather than falling back to the logged code below.
      connectionTimeout: 10_000,
      greetingTimeout: 10_000,
      socketTimeout: 20_000,
    });
  }
  return transporter;
};

export const sendEmail = async (
  to: string,
  subject: string,
  text: string,
): Promise<boolean> => {
  if (!isMailConfigured()) {
    // Not configured: fall back to the server log so development still works.
    console.log(`[MAIL to=${to}] ${subject}\n${text}`);
    return false;
  }

  const from = process.env.SMTP_FROM ?? process.env.SMTP_USER!;

  try {
    await getTransporter().sendMail({ from, to, subject, text });
    return true;
  } catch (error) {
    // Delivery is best-effort: report the failure and let the caller surface
    // the code another way instead of failing the whole request.
    console.error(`[MAIL to=${to}] send failed:`, error);
    console.log(`[MAIL to=${to}] ${subject}\n${text}`);
    return false;
  }
};
