import nodemailer from "nodemailer";

type SectorTestMailInput = {
  sectorName: string;
  recipients: string[];
};

function isValidEmail(value: string) {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
}

function escapeHtml(value: string) {
  return value
    .replaceAll("&", "&amp;")
    .replaceAll("<", "&lt;")
    .replaceAll(">", "&gt;")
    .replaceAll('"', "&quot;")
    .replaceAll("'", "&#039;");
}

function getAllowedRecipients() {
  return new Set(
    (process.env.SECTOR_MAIL_TEST_ALLOWED_RECIPIENTS ?? "")
      .split(/[;,]/)
      .map((email) => email.trim().toLowerCase())
      .filter((email) => isValidEmail(email)),
  );
}

function validateRecipients(recipients: string[]) {
  if (recipients.length === 0) {
    throw new Error("SECTOR_TEST_MAIL_NO_RECIPIENT");
  }

  const allowedRecipients = getAllowedRecipients();

  if (allowedRecipients.size === 0) {
    throw new Error("SECTOR_TEST_MAIL_EMPTY_ALLOWLIST");
  }

  const normalizedRecipients = [
    ...new Set(
      recipients.map((email) => email.trim().toLowerCase()),
    ),
  ];

  const invalidRecipient = normalizedRecipients.find(
    (email) =>
      !isValidEmail(email) || !allowedRecipients.has(email),
  );

  if (invalidRecipient) {
    throw new Error(
      `SECTOR_TEST_MAIL_RECIPIENT_NOT_ALLOWED:${invalidRecipient}`,
    );
  }

  return normalizedRecipients;
}

function buildSectorTestMail(sectorName: string) {
  const subject = `[TEST] RH Connect - Alertes secteur - ${sectorName}`;
  const formattedDate = new Intl.DateTimeFormat("fr-FR", {
    dateStyle: "full",
    timeStyle: "medium",
    timeZone: "Europe/Paris",
  }).format(new Date());

  const html = `<!doctype html>
<html lang="fr">
  <head>
    <meta charset="utf-8">
    <title>${escapeHtml(subject)}</title>
  </head>
  <body style="margin:0;background:#f8fafc;font-family:Arial,sans-serif;color:#0f172a;">
    <div style="max-width:760px;margin:0 auto;padding:24px;">
      <div style="background:#fff;border:1px solid #cbd5e1;padding:24px;">
        <div style="display:inline-block;margin-bottom:18px;padding:6px 10px;background:#fef3c7;color:#92400e;font-size:12px;font-weight:700;">
          TEST ANONYMISÉ — AUCUNE DONNÉE RH RÉELLE
        </div>

        <h1 style="margin:0 0 6px;color:#0369a1;font-size:26px;">
          Test des alertes par secteur
        </h1>
        <p style="margin:0 0 26px;color:#64748b;">
          Secteur testé : ${escapeHtml(sectorName)}
        </p>

        <section style="margin-bottom:24px;">
          <h2 style="margin:0 0 10px;font-size:20px;">
            Exemple d’alerte fictive
          </h2>
          <ul style="margin:0;padding-left:24px;color:#475569;">
            <li style="margin-bottom:8px;">
              SALARIÉ TEST : document fictif à renouveler le 31/12/2030
            </li>
          </ul>
        </section>

        <p style="margin:28px 0 0;padding-top:18px;border-top:1px solid #e2e8f0;color:#64748b;font-size:13px;">
          Mail de test généré par RH Connect le ${escapeHtml(formattedDate)}.
          Aucun nom de salarié ni aucune donnée RH réelle n’ont été utilisés.
        </p>
      </div>
    </div>
  </body>
</html>`;

  const text = [
    "TEST ANONYMISÉ — AUCUNE DONNÉE RH RÉELLE",
    "",
    "Test des alertes par secteur",
    `Secteur testé : ${sectorName}`,
    "",
    "Exemple d’alerte fictive :",
    "SALARIÉ TEST : document fictif à renouveler le 31/12/2030",
    "",
    `Mail de test généré par RH Connect le ${formattedDate}.`,
  ].join("\n");

  return {
    subject,
    html,
    text,
  };
}

export async function sendAnonymizedSectorTestMail(
  input: SectorTestMailInput,
) {
  if (
    process.env.SECTOR_MAIL_TEST_ENABLED?.toLowerCase() !==
    "true"
  ) {
    throw new Error("SECTOR_TEST_MAIL_DISABLED");
  }

  const smtpUser = process.env.MAIL_TEST_SMTP_USER
    ?.trim()
    .toLowerCase();
  const smtpAppPassword = process.env.MAIL_TEST_SMTP_APP_PASSWORD
    ?.replace(/\s+/g, "")
    .trim();

  if (!smtpUser || !isValidEmail(smtpUser) || !smtpAppPassword) {
    throw new Error("SECTOR_TEST_MAIL_INVALID_SMTP_CONFIGURATION");
  }

  const recipients = validateRecipients(input.recipients);
  const mail = buildSectorTestMail(input.sectorName);

  const transporter = nodemailer.createTransport({
    host: "smtp.gmail.com",
    port: 465,
    secure: true,
    auth: {
      user: smtpUser,
      pass: smtpAppPassword,
    },
    connectionTimeout: 15_000,
    greetingTimeout: 10_000,
    socketTimeout: 20_000,
  });

  const result = await transporter.sendMail({
    from: `"RH Connect - Test" <${smtpUser}>`,
    bcc: recipients,
    subject: mail.subject,
    text: mail.text,
    html: mail.html,
    disableFileAccess: true,
    disableUrlAccess: true,
  });

  return {
    messageId: result.messageId,
    recipients,
    subject: mail.subject,
    accepted: result.accepted.map(String),
    rejected: result.rejected.map(String),
    sentAt: new Date().toISOString(),
    anonymized: true,
  };
}
