import { NextResponse } from "next/server";

import { requireAuth } from "@/lib/requireAuth";
import {
  ALERT_MAIL_GROUPS,
  isAlertMailGroup,
} from "@/services/alertes-mail.service";
import { sendAlertMailWithGraph } from "@/services/alertes-mail-graph.service";

export const dynamic = "force-dynamic";

const CONFIRMATION_VALUE = "ENVOYER_TEST";
const DEFAULT_COOLDOWN_SECONDS = 60;

let lastTestMailSentAt = 0;
let testMailSending = false;

function noStoreHeaders() {
  return {
    "Cache-Control": "no-store",
  };
}

function isGraphTestEnabled() {
  return process.env.ALERT_MAIL_GRAPH_TEST_ENABLED?.trim().toLowerCase() === "true";
}

function getTestRecipients() {
  return (process.env.ALERT_MAIL_GRAPH_TEST_RECIPIENTS ?? "")
    .split(/[;,]/)
    .map((recipient) => recipient.trim().toLowerCase())
    .filter(Boolean);
}

function getCooldownSeconds() {
  const value = Number(process.env.ALERT_MAIL_GRAPH_TEST_COOLDOWN_SECONDS);

  if (!Number.isFinite(value) || value < 1) {
    return DEFAULT_COOLDOWN_SECONDS;
  }

  return Math.floor(value);
}

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

export async function POST(request: Request) {
  const authError = requireAuth(request);

  if (authError) {
    return authError;
  }

  let body: unknown;

  try {
    body = await request.json();
  } catch {
    return NextResponse.json(
      { message: "Corps JSON invalide" },
      { status: 400, headers: noStoreHeaders() },
    );
  }

  const requestedGroup =
    typeof body === "object" &&
    body !== null &&
    "groupe" in body &&
    typeof body.groupe === "string"
      ? body.groupe.trim().toLocaleLowerCase("fr")
      : "";

  const confirmation =
    typeof body === "object" &&
    body !== null &&
    "confirmation" in body &&
    typeof body.confirmation === "string"
      ? body.confirmation
      : "";

  if (!isAlertMailGroup(requestedGroup)) {
    return NextResponse.json(
      {
        message: "Groupe destinataire invalide",
        allowedGroups: ALERT_MAIL_GROUPS,
      },
      { status: 400, headers: noStoreHeaders() },
    );
  }

  if (confirmation !== CONFIRMATION_VALUE) {
    return NextResponse.json(
      { message: "Confirmation d'envoi de test invalide" },
      { status: 400, headers: noStoreHeaders() },
    );
  }

  if (!isGraphTestEnabled()) {
    return NextResponse.json(
      {
        message:
          "L'envoi de test Microsoft Graph est désactivé dans la configuration du serveur.",
      },
      { status: 503, headers: noStoreHeaders() },
    );
  }

  const recipients = getTestRecipients();

  if (recipients.length === 0) {
    return NextResponse.json(
      {
        message:
          "Aucun destinataire de test Microsoft Graph n'est configuré sur le serveur.",
      },
      { status: 503, headers: noStoreHeaders() },
    );
  }

  const cooldownSeconds = getCooldownSeconds();
  const elapsedMilliseconds = Date.now() - lastTestMailSentAt;
  const cooldownMilliseconds = cooldownSeconds * 1_000;

  if (lastTestMailSentAt > 0 && elapsedMilliseconds < cooldownMilliseconds) {
    const retryAfter = Math.ceil(
      (cooldownMilliseconds - elapsedMilliseconds) / 1_000,
    );

    return NextResponse.json(
      {
        message: `Un mail de test vient déjà d'être envoyé. Réessaie dans ${retryAfter} seconde(s).`,
        retryAfter,
      },
      {
        status: 429,
        headers: {
          ...noStoreHeaders(),
          "Retry-After": String(retryAfter),
        },
      },
    );
  }

  if (testMailSending) {
    return NextResponse.json(
      { message: "Un envoi de test est déjà en cours." },
      {
        status: 429,
        headers: {
          ...noStoreHeaders(),
          "Retry-After": "5",
        },
      },
    );
  }

  testMailSending = true;

  try {
    const safeGroup = escapeHtml(requestedGroup);
    const result = await sendAlertMailWithGraph({
      recipients,
      subject: `[RH Connect] Test Microsoft Graph - ${requestedGroup}`,
      html: `
        <h1>Test d'envoi RH Connect</h1>
        <p>Ce message confirme que RH Connect peut envoyer un mail avec Microsoft Graph.</p>
        <p><strong>Groupe testé :</strong> ${safeGroup}</p>
        <p>Aucune donnée RH réelle n'est incluse dans ce message.</p>
      `,
    });

    lastTestMailSentAt = Date.now();

    return NextResponse.json(
      {
        message: `Mail de test Microsoft Graph envoyé à ${recipients.join(", ")}.`,
        item: {
          recipients,
          group: requestedGroup,
          messageId: result.messageId,
        },
      },
      { headers: noStoreHeaders() },
    );
  } catch (error) {
    console.error("Erreur lors du test d'envoi Microsoft Graph :", error);

    const errorCode = error instanceof Error ? error.message : "";

    if (
      errorCode.endsWith("_MISSING") ||
      errorCode === "ALERT_MAIL_INVALID_FROM_EMAIL" ||
      errorCode === "ALERT_MAIL_INVALID_RECIPIENT" ||
      errorCode === "ALERT_MAIL_NO_RECIPIENT"
    ) {
      return NextResponse.json(
        {
          message:
            "La configuration Microsoft Graph ou les adresses de test sont absentes ou invalides sur le serveur.",
        },
        { status: 503, headers: noStoreHeaders() },
      );
    }

    return NextResponse.json(
      {
        message:
          "Échec du test Microsoft Graph. Vérifie l'autorisation Mail.Send et les journaux du backend.",
      },
      { status: 502, headers: noStoreHeaders() },
    );
  } finally {
    testMailSending = false;
  }
}
