import nodemailer from "nodemailer";

/**
 * SMTP mail sender for form notifications (contact, newsletter, blog subscribe).
 *
 * Configuration is entirely via environment variables so no secret ever lives in
 * the repo. Set these in `.env.local` (dev) or your hosting provider's env (prod):
 *
 *   SMTP_HOST      e.g. smtp.gmail.com | smtp.zoho.com | smtp.hostinger.com
 *   SMTP_PORT      465 (SSL) or 587 (STARTTLS)          [default 587]
 *   SMTP_SECURE    "true" for port 465, else "false"    [default: true if port 465]
 *   SMTP_USER      the mailbox login (usually the full email address)
 *   SMTP_PASS      the mailbox password / app-password
 *   MAIL_FROM      From header, e.g. "Quto AI <no-reply@qutoai.com>" [default: SMTP_USER]
 *   CONTACT_TO     where leads are delivered      [default website@imgglobalinfotech.com]
 *
 * Nothing here runs at import time; the transporter is created lazily and cached.
 * This module is imported only by API route handlers, so it never reaches the
 * client bundle (and nodemailer/process.env could not run there anyway).
 */

const DEFAULT_TO = "website@imgglobalinfotech.com";

export function mailRecipient(): string {
  return process.env.CONTACT_TO?.trim() || DEFAULT_TO;
}

export function isMailConfigured(): boolean {
  return Boolean(process.env.SMTP_HOST && process.env.SMTP_USER && process.env.SMTP_PASS);
}

type Transporter = ReturnType<typeof nodemailer.createTransport>;

let cached: Transporter | null = null;

function transporter(): Transporter {
  if (cached) return cached;
  const host = process.env.SMTP_HOST;
  const user = process.env.SMTP_USER;
  const pass = process.env.SMTP_PASS;
  if (!host || !user || !pass) {
    throw new MailNotConfiguredError();
  }
  const port = Number(process.env.SMTP_PORT) || 587;
  // Port 465 is implicit TLS; 587/25 use STARTTLS. Allow an explicit override.
  const secure =
    process.env.SMTP_SECURE != null
      ? process.env.SMTP_SECURE.toLowerCase() === "true"
      : port === 465;
  cached = nodemailer.createTransport({ host, port, secure, auth: { user, pass } });
  return cached;
}

/** Thrown when SMTP env vars are absent, so callers can treat it distinctly. */
export class MailNotConfiguredError extends Error {
  constructor() {
    super("SMTP is not configured (set SMTP_HOST, SMTP_USER, SMTP_PASS).");
    this.name = "MailNotConfiguredError";
  }
}

export interface SendMailInput {
  /** Target email address. Defaults to mailRecipient() if omitted. */
  to?: string;
  subject: string;
  text: string;
  html?: string;
  /** Set to the submitter's address so a reply goes straight to them. */
  replyTo?: string;
}

/**
 * Sends one email notification. Throws `MailNotConfiguredError` if SMTP env is
 * missing, or the underlying transport error on failure.
 */
export async function sendMail({ to, subject, text, html, replyTo }: SendMailInput) {
  const from = process.env.MAIL_FROM?.trim() || process.env.SMTP_USER || "Quto AI <hello@qutoai.com>";
  const targetRecipient = to?.trim() || mailRecipient();
  return transporter().sendMail({ from, to: targetRecipient, subject, text, html, replyTo });
}

/**
 * Collapses CR/LF (and trims) so user input is safe to interpolate into a
 * single-line header such as the Subject — defence-in-depth against header
 * injection, on top of nodemailer's own header sanitisation.
 */
export function headerSafe(value: string): string {
  return value.replace(/[\r\n]+/g, " ").trim();
}

/** Minimal HTML-escaping for interpolating user input into the HTML email body. */
export function escapeHtml(value: string): string {
  return value
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;")
    .replace(/'/g, "&#39;");
}
