import "server-only";

import nodemailer from "nodemailer";

type SendEmailInput = {
  to: string;
  subject: string;
  text: string;
  html: string;
};

type SmtpConfig = {
  host: string;
  port: number;
  secure: boolean;
  user: string;
  pass: string;
  from: string;
  connectionTimeoutMs: number;
  greetingTimeoutMs: number;
  socketTimeoutMs: number;
};

let transporter: nodemailer.Transporter | null = null;

function asBoolean(value: string | undefined, fallback: boolean) {
  if (!value) {
    return fallback;
  }

  const normalized = value.trim().toLowerCase();
  return normalized === "1" || normalized === "true" || normalized === "yes";
}

function asPositiveInt(value: string | undefined, fallback: number) {
  const parsed = Number.parseInt(value?.trim() ?? "", 10);

  if (Number.isNaN(parsed) || parsed <= 0) {
    return fallback;
  }

  return parsed;
}

function getSmtpConfig(): SmtpConfig | null {
  const host = process.env.SMTP_HOST?.trim();
  const portRaw = process.env.SMTP_PORT?.trim() || "587";
  const port = Number.parseInt(portRaw, 10);
  const user = process.env.SMTP_USER?.trim();
  const pass = process.env.SMTP_PASS?.trim() || process.env.SMTP_PASSWORD?.trim();
  const from = process.env.SMTP_FROM?.trim();

  if (!host || !port || Number.isNaN(port) || !user || !pass || !from) {
    return null;
  }

  // Port 465 requires TLS from the beginning of the connection.
  // Keep SMTP_SECURE for 587/STARTTLS, but force secure mode on 465 to avoid hangs.
  const secure = port === 465 ? true : asBoolean(process.env.SMTP_SECURE, false);
  const connectionTimeoutMs = asPositiveInt(process.env.SMTP_CONNECTION_TIMEOUT_MS, 10000);
  const greetingTimeoutMs = asPositiveInt(process.env.SMTP_GREETING_TIMEOUT_MS, 10000);
  const socketTimeoutMs = asPositiveInt(process.env.SMTP_SOCKET_TIMEOUT_MS, 20000);

  return { host, port, secure, user, pass, from, connectionTimeoutMs, greetingTimeoutMs, socketTimeoutMs };
}

function getTransporter(config: SmtpConfig) {
  if (!transporter) {
    transporter = nodemailer.createTransport({
      host: config.host,
      port: config.port,
      secure: config.secure,
      connectionTimeout: config.connectionTimeoutMs,
      greetingTimeout: config.greetingTimeoutMs,
      socketTimeout: config.socketTimeoutMs,
      auth: {
        user: config.user,
        pass: config.pass,
      },
    });
  }

  return transporter;
}

export function isSmtpConfigured() {
  return Boolean(getSmtpConfig());
}

export async function sendEmail(input: SendEmailInput) {
  const config = getSmtpConfig();

  if (!config) {
    throw new Error("SMTP is not configured. Required env vars: SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, SMTP_FROM.");
  }

  const smtpTransporter = getTransporter(config);

  await smtpTransporter.sendMail({
    from: config.from,
    to: input.to,
    subject: input.subject,
    text: input.text,
    html: input.html,
  });
}
