import path from "node:path";

import PDFDocument from "pdfkit";

import type { AttestationRetraitePdfData } from "@/services/impressions.service";

function formatLongFrenchDate(value: string) {
  const [year, month, day] = value.split("-").map(Number);

  if (!year || !month || !day) return value;

  const formatted = new Intl.DateTimeFormat("fr-FR", {
    timeZone: "Europe/Paris",
    day: "numeric",
    month: "long",
    year: "numeric",
  }).format(new Date(Date.UTC(year, month - 1, day, 12)));

  return day === 1 ? formatted.replace(/^1 /, "1er ") : formatted;
}

function qualitePoste(poste: string) {
  const firstLetter = poste
    .trim()
    .normalize("NFD")
    .replace(/[\u0300-\u036f]/g, "")
    .charAt(0)
    .toLowerCase();

  return "aeiouyh".includes(firstLetter) ? `d'${poste}` : `de ${poste}`;
}

export async function renderAttestationRetraitePdf(
  data: AttestationRetraitePdfData,
): Promise<Buffer> {
  return new Promise((resolve, reject) => {
    const chunks: Buffer[] = [];
    const regularFontPath = path.join(
      process.cwd(),
      "public",
      "fonts",
      "DejaVuSans.ttf",
    );
    const boldFontPath = path.join(
      process.cwd(),
      "public",
      "fonts",
      "DejaVuSans-Bold.ttf",
    );
    const document = new PDFDocument({
      size: "A4",
      margins: { top: 0, right: 0, bottom: 0, left: 0 },
      font: regularFontPath,
      info: {
        Title: `Attestation retraite - ${data.titreNomPrenom}`,
        Author: "RH Connect",
        Subject: "Attestation de départ à la retraite",
      },
      compress: true,
    });

    document.on("data", (chunk: Buffer) => chunks.push(chunk));
    document.on("end", () => resolve(Buffer.concat(chunks)));
    document.on("error", reject);

    const pageWidth = document.page.width;
    const margin = 72;
    const contentWidth = pageWidth - margin * 2;

    document.registerFont("DocumentRegular", regularFontPath);
    document.registerFont("DocumentBold", boldFontPath);

    document
      .lineWidth(0.75)
      .rect(margin, 218, contentWidth, 24)
      .stroke("#111111");
    document
      .font("DocumentBold")
      .fontSize(15)
      .fillColor("#111111")
      .text("ATTESTATION", margin, 222, {
        width: contentWidth,
        align: "center",
      });

    const introduction = `Je ${data.formuleSoussignataire}, ${data.signataireNom} - ${data.signataireFonction} de la ${data.entreprise}, atteste par la présente que ${data.titreNomPrenom} ${data.domicilie} ${data.adresseLigne} travaille au sein de notre société en ${data.typeContrat} depuis le ${formatLongFrenchDate(data.dateEmbauche)} en qualité ${qualitePoste(data.poste)} et est dans nos effectifs jusqu'au ${formatLongFrenchDate(data.dateSortiePrevue)}. Le ${formatLongFrenchDate(data.dateRetraite)}, ${data.titreNomPrenom} fera valoir ses droits à la retraite.`;

    document
      .font("DocumentRegular")
      .fontSize(11.5)
      .fillColor("#111111")
      .text(introduction, margin + 4, 314, {
        width: contentWidth - 8,
        align: "justify",
        lineGap: 2.5,
      });

    const closingY = Math.max(document.y + 48, 486);
    document.text("Pour faire et valoir ce que de droit.", 108, closingY, {
      width: 300,
      align: "left",
    });

    const signatureWidth = 225;
    const signatureX = pageWidth - margin - signatureWidth;
    const signatureDateY = Math.max(552, document.y + 62);
    document.text(
      `Fait à ${data.lieuDocument},\nLe ${formatLongFrenchDate(data.dateDocument)}.`,
      signatureX,
      signatureDateY,
      {
        width: signatureWidth,
        align: "right",
        lineGap: 2,
      },
    );
    document.text(
      `${data.signataireNom}\n${data.signataireFonction}`,
      signatureX - 40,
      signatureDateY + 70,
      {
        width: signatureWidth + 40,
        align: "right",
        lineGap: 2,
      },
    );

    document.end();
  });
}
