import nodemailer from "nodemailer";
import type { Transporter } from "nodemailer";
import { env } from "@/lib/runtime-env";

export type MailProject = {
  requestType?: "sign" | "textile" | "neon" | "project" | "application";
  requestId?: number;
};

type TrackedMail = MailProject & {
  template: string;
  to: string;
  subject: string;
  text: string;
  html?: string;
  replyTo?: string;
};

let transport: Transporter | null = null;

function mailTransport() {
  if (transport) return transport;
  const user = process.env.SMTP_USER;
  const pass = process.env.SMTP_PASSWORD;
  if (!user || !pass) throw new Error("Configuration SMTP incomplète.");
  const secure = String(process.env.SMTP_SECURE || "true").toLowerCase() === "true";
  transport = nodemailer.createTransport({
    host: process.env.SMTP_HOST || "smtp.ionos.fr",
    port: Number(process.env.SMTP_PORT || (secure ? 465 : 587)),
    secure,
    auth: { user, pass },
    pool: true,
    maxConnections: 2,
    maxMessages: 50,
  });
  return transport;
}

export function siteUrl() {
  return (process.env.NEXT_PUBLIC_SITE_URL || "https://pyramidcom.fr").replace(/\/+$/, "");
}

export function projectsMailbox() {
  return process.env.MAIL_REPLY_TO || "projets@pyramidcom.fr";
}

export async function sendTrackedMail(input: TrackedMail) {
  const recipient = input.to.trim().toLowerCase();
  const now = Date.now();
  try {
    const info = await mailTransport().sendMail({
      from: process.env.MAIL_FROM || "PyramidCom <noreply@pyramidcom.fr>",
      to: recipient,
      replyTo: input.replyTo || projectsMailbox(),
      subject: input.subject,
      text: input.text,
      html: input.html,
    });
    await writeLog(input, recipient, "sent", info.messageId || null, null, now);
    return { success: true as const, messageId: info.messageId || null };
  } catch (error) {
    const message = error instanceof Error ? error.message.slice(0, 1_000) : "Erreur SMTP inconnue.";
    await writeLog(input, recipient, "failed", null, message, now).catch(() => undefined);
    return { success: false as const, error: message };
  }
}

async function writeLog(
  input: TrackedMail,
  recipient: string,
  status: "sent" | "failed",
  messageId: string | null,
  errorMessage: string | null,
  createdAt: number,
) {
  await env.DB.prepare(`INSERT INTO email_logs
    (request_type, request_id, template, recipient, subject, status, message_id, error_message, created_at)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`)
    .bind(input.requestType || null, input.requestId || null, input.template.slice(0, 80), recipient,
      input.subject.slice(0, 255), status, messageId, errorMessage, createdAt).run();
}
