import { createTransport, type Transporter } from 'nodemailer';
import { readServerSettings } from 'officerdb';

// Configured from Settings → Server → SMTP, and from nowhere else.
//
// There was a MAIL_TRANSPORT fallback here until 2026-08-12, left from the old registration flow that
// sent confirmation mail. It outlived that flow and became a second source of truth for something the
// owner can already set in the UI — with the failure mode that a stale URL in .env silently answered
// for a server whose settings row was simply empty. Absent settings now raise, which is the honest
// answer and points at the screen that fixes it.

type SmtpConfig = {
  provider: 'resend' | 'smtp' | 'mailhog';
  apiKey?: string;
  host?: string;
  port?: number;
  username?: string;
  password?: string;
  secure?: boolean;
  fromName: string;
  fromEmail: string;
};

let cachedTransport: Transporter | null = null;
let cachedConfigHash: string | null = null;

function buildTransportUrl(config: SmtpConfig): string {
  if (config.provider === 'mailhog') {
    return `smtp://${config.host ?? 'localhost'}:${config.port ?? 1025}`;
  }
  const auth = config.username ? `${encodeURIComponent(config.username)}:${encodeURIComponent(config.password ?? '')}@` : '';
  const protocol = config.secure ? 'smtps' : 'smtp';
  return `${protocol}://${auth}${config.host}:${config.port ?? 587}`;
}

type SmtpTransport = { type: 'smtp'; transport: Transporter; from: string | null };
type ResendTransport = { type: 'resend'; apiKey: string; from: string };
export type TransportResult = SmtpTransport | ResendTransport;

export async function getTransport(): Promise<TransportResult> {
  // Only the read is guarded. Three outcomes that used to be one — the database is unreachable, nothing
  // is configured, and the stored settings do not build a transport — say different things now, because
  // the fix for each is different and the caller only ever sees this message.
  let settings: Record<string, unknown>;
  try {
    settings = await readServerSettings();
  } catch (ex) {
    throw new Error(`Could not read the SMTP settings: ${ex instanceof Error ? ex.message : String(ex)}`);
  }

  const smtp: SmtpConfig | undefined = settings.smtp as SmtpConfig | undefined;
  if (!smtp) throw new Error('No email transport configured — set one in Settings → Server → SMTP');

  const from = `${smtp.fromName} <${smtp.fromEmail}>`;

  if (smtp.provider === 'resend') {
    return { type: 'resend', apiKey: smtp.apiKey ?? '', from };
  }

  const hash = JSON.stringify(smtp);
  if (cachedTransport && cachedConfigHash === hash) {
    return { type: 'smtp', transport: cachedTransport, from };
  }
  const url = buildTransportUrl(smtp);
  cachedTransport = createTransport(url);
  cachedConfigHash = hash;
  return { type: 'smtp', transport: cachedTransport, from };
}
