import fs from "node:fs";
import path from "node:path";
import PDFDocument from "pdfkit";

const OUTPUT_DIR = path.resolve(process.cwd(), "exports/factures");
const OUTPUT_BASENAME = "facture-honnete-ccds-portail-ovh-2026-06-11";
const OUTPUT_PDF = path.join(OUTPUT_DIR, `${OUTPUT_BASENAME}.pdf`);
const OUTPUT_JSON = path.join(OUTPUT_DIR, `${OUTPUT_BASENAME}.json`);
const LOGO_PATH = path.resolve(process.cwd(), "client/src/assets/ccds.png");

const invoice = {
  status: "FACTURE A COMPLETER AVANT ENVOI",
  invoiceNumber: "FA-CCDS-2026-06-11-HONNETE",
  issueDate: "11/06/2026",
  dueDate: "A completer",
  issuer: {
    name: "Nom / raison sociale a completer",
    addressLines: ["Adresse a completer", "Code postal et ville a completer"],
    siret: "SIRET a completer",
    email: "Email a completer",
    phone: "Telephone a completer",
    vat: "Regime TVA a completer",
  },
  recipient: {
    name: "Communaute de Communes des Savanes",
    addressLines: ["Quartier Cabalou", "1 rue Raymond Cresson", "97310 Kourou"],
    siret: "200 027 548 00029",
  },
  project: {
    title: "Portail des associations CCDS",
    url: "https://www.portail-association973.com",
  },
  lineItems: [
    {
      label: "Realisation et finalisation du portail des associations CCDS",
      details: [
        "Conception, developpement, integration, corrections et mise en coherence generale",
        "Projet concerne : https://www.portail-association973.com",
      ],
      quantity: "1",
      unitPrice: "6 000,00 EUR",
      total: "6 000,00 EUR",
    },
    {
      label: "Location / hebergement des serveurs OVH",
      details: [
        "Infrastructure OVH utilisee pour le projet",
        "Periode de facturation a completer",
      ],
      quantity: "1",
      unitPrice: "300,00 EUR",
      total: "300,00 EUR",
    },
  ],
  totals: {
    subtotalHt: "6 300,00 EUR",
    vatAmount: "A verifier selon regime",
    totalTtc: "6 300,00 EUR si TVA non applicable",
  },
  notes: [
    "Facture volontairement sobre et centree sur le travail reellement fourni pour le portail et l'hebergement OVH.",
    "RIB / IBAN, regime TVA, echeance et periode exacte OVH a completer avant envoi.",
  ],
};

function ensureDir(dir) {
  fs.mkdirSync(dir, { recursive: true });
}

function drawLogo(doc, x, y, width, height) {
  if (!fs.existsSync(LOGO_PATH)) return;
  try {
    doc.image(LOGO_PATH, x, y, { fit: [width, height], align: "left", valign: "center" });
  } catch {}
}

function drawBox(doc, x, y, width, height, fill = "#ffffff", stroke = "#cbd5e1") {
  doc.save();
  doc.roundedRect(x, y, width, height, 8).fillAndStroke(fill, stroke);
  doc.restore();
}

function label(doc, text, x, y, width) {
  doc.font("Helvetica-Bold").fontSize(9).fillColor("#64748b").text(text.toUpperCase(), x, y, { width });
}

function value(doc, text, x, y, width, options = {}) {
  doc.font("Helvetica").fontSize(10.5).fillColor("#0f172a").text(text, x, y, { width, ...options });
}

function heightOf(doc, text, width, fontName, fontSize) {
  doc.font(fontName).fontSize(fontSize);
  return doc.heightOfString(text, { width });
}

async function render() {
  ensureDir(OUTPUT_DIR);
  fs.writeFileSync(OUTPUT_JSON, JSON.stringify(invoice, null, 2));

  const doc = new PDFDocument({
    size: "A4",
    margins: { top: 38, bottom: 42, left: 38, right: 38 },
    info: {
      Title: "Facture honnête CCDS - portail et OVH",
      Author: "Codex",
      Subject: "Facture a completer pour la CCDS",
    },
  });

  const chunks = [];
  doc.on("data", (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
  const done = new Promise((resolve, reject) => {
    doc.on("end", () => resolve(Buffer.concat(chunks)));
    doc.on("error", reject);
  });

  const pageWidth = doc.page.width - doc.page.margins.left - doc.page.margins.right;
  const left = doc.page.margins.left;
  let y = doc.page.margins.top;

  doc.save();
  doc.rect(0, 0, doc.page.width, 26).fill("#fff7ed");
  doc.restore();
  doc.font("Helvetica-Bold").fontSize(10).fillColor("#c2410c").text(invoice.status, left, 8, { width: pageWidth, align: "center" });

  drawLogo(doc, left, y + 8, 80, 80);
  doc.font("Helvetica-Bold").fontSize(24).fillColor("#0f172a").text("FACTURE", left + 96, y + 8, { width: 180 });
  doc.font("Helvetica").fontSize(11).fillColor("#475569").text(invoice.project.title, left + 96, y + 40, { width: 240 });
  doc.font("Helvetica-Bold").fontSize(11).fillColor("#1d4ed8").text(invoice.project.url, left + 96, y + 58, { width: 280 });

  const rightX = left + pageWidth - 220;
  drawBox(doc, rightX, y + 4, 220, 92, "#f8fafc");
  label(doc, "Numero", rightX + 14, y + 16, 80);
  value(doc, invoice.invoiceNumber, rightX + 14, y + 30, 190);
  label(doc, "Date", rightX + 14, y + 52, 80);
  value(doc, invoice.issueDate, rightX + 14, y + 66, 70);
  label(doc, "Echeance", rightX + 112, y + 52, 80);
  value(doc, invoice.dueDate, rightX + 112, y + 66, 94);
  y += 116;

  const gap = 16;
  const half = (pageWidth - gap) / 2;
  drawBox(doc, left, y, half, 112);
  drawBox(doc, left + half + gap, y, half, 112, "#f8fafc");

  label(doc, "Emetteur / prestataire", left + 14, y + 14, half - 28);
  value(doc, invoice.issuer.name, left + 14, y + 32, half - 28);
  value(doc, invoice.issuer.addressLines.join("\n"), left + 14, y + 48, half - 28);
  value(doc, `SIRET : ${invoice.issuer.siret}`, left + 14, y + 78, half - 28);
  value(doc, `${invoice.issuer.email}  •  ${invoice.issuer.phone}`, left + 14, y + 92, half - 28);

  const dx = left + half + gap + 14;
  label(doc, "Destinataire", dx, y + 14, half - 28);
  doc.font("Helvetica-Bold").fontSize(11).fillColor("#0f172a").text(invoice.recipient.name, dx, y + 32, { width: half - 28 });
  value(doc, invoice.recipient.addressLines.join("\n"), dx, y + 50, half - 28);
  value(doc, `SIRET : ${invoice.recipient.siret}`, dx, y + 92, half - 28);
  y += 134;

  drawBox(doc, left, y, pageWidth, 64, "#eff6ff", "#bfdbfe");
  label(doc, "Objet", left + 14, y + 12, 120);
  doc.font("Helvetica-Bold").fontSize(12).fillColor("#1e3a8a").text(
    "Facturation du portail des associations CCDS et de la location des serveurs OVH",
    left + 14,
    y + 28,
    { width: pageWidth - 28 }
  );
  y += 88;

  doc.font("Helvetica-Bold").fontSize(12).fillColor("#0f172a").text("Lignes de facturation", left, y);
  y += 18;

  const cols = { desc: pageWidth * 0.64, qty: pageWidth * 0.08, unit: pageWidth * 0.13, total: pageWidth * 0.15 };
  doc.save();
  doc.rect(left, y, pageWidth, 32).fill("#0f172a");
  doc.restore();
  doc.font("Helvetica-Bold").fontSize(9.5).fillColor("#ffffff");
  doc.text("DESCRIPTION", left + 10, y + 11, { width: cols.desc - 20 });
  doc.text("QTE", left + cols.desc, y + 11, { width: cols.qty, align: "center" });
  doc.text("PRIX", left + cols.desc + cols.qty, y + 11, { width: cols.unit, align: "center" });
  doc.text("TOTAL", left + cols.desc + cols.qty + cols.unit, y + 11, { width: cols.total, align: "center" });
  y += 32;

  for (const item of invoice.lineItems) {
    const details = item.details.map((detail) => `- ${detail}`).join("\n");
    const width = cols.desc - 20;
    const titleH = heightOf(doc, item.label, width, "Helvetica-Bold", 10.5);
    const detailsH = heightOf(doc, details, width, "Helvetica", 9.5);
    const detailsY = y + 12 + titleH + 6;
    const rowH = Math.max(78, 12 + titleH + 6 + detailsH + 14);

    [0, cols.desc, cols.desc + cols.qty, cols.desc + cols.qty + cols.unit].forEach((offset, index) => {
      const w = index === 0 ? cols.desc : index === 1 ? cols.qty : index === 2 ? cols.unit : cols.total;
      doc.rect(left + offset, y, w, rowH).stroke("#cbd5e1");
    });

    doc.font("Helvetica-Bold").fontSize(10.5).fillColor("#0f172a").text(item.label, left + 10, y + 10, { width });
    doc.font("Helvetica").fontSize(9.5).fillColor("#475569").text(details, left + 10, detailsY, { width });
    doc.font("Helvetica-Bold").fontSize(10).fillColor("#0f172a")
      .text(item.quantity, left + cols.desc, y + rowH / 2 - 7, { width: cols.qty, align: "center" })
      .text(item.unitPrice, left + cols.desc + cols.qty + 4, y + rowH / 2 - 7, { width: cols.unit - 8, align: "center" })
      .text(item.total, left + cols.desc + cols.qty + cols.unit + 4, y + rowH / 2 - 7, { width: cols.total - 8, align: "center" });
    y += rowH;
  }

  y += 16;
  const totalsW = 220;
  const totalsX = left + pageWidth - totalsW;
  drawBox(doc, totalsX, y, totalsW, 92, "#f8fafc");
  [
    ["Sous-total HT", invoice.totals.subtotalHt],
    ["TVA", invoice.totals.vatAmount],
    ["Total TTC", invoice.totals.totalTtc],
  ].forEach(([l, v], i) => {
    const ty = y + 16 + i * 24;
    doc.font(i === 2 ? "Helvetica-Bold" : "Helvetica").fontSize(i === 2 ? 11.5 : 10).fillColor("#0f172a");
    doc.text(l, totalsX + 14, ty, { width: 100 });
    doc.text(v, totalsX + 110, ty, { width: 96, align: "right" });
  });
  y += 112;

  drawBox(doc, left, y, pageWidth, 88, "#fff7ed", "#fdba74");
  label(doc, "Notes", left + 14, y + 14, 100);
  doc.font("Helvetica").fontSize(10).fillColor("#7c2d12").text(invoice.notes.join("\n\n"), left + 14, y + 32, { width: pageWidth - 28 });
  y += 110;

  doc.font("Helvetica").fontSize(9).fillColor("#64748b").text(
    "Version preparee pour la CCDS. Verifier avant envoi les informations emetteur, la TVA, l'echeance et le RIB.",
    left,
    y,
    { width: pageWidth, align: "center" }
  );

  doc.end();
  const buffer = await done;
  fs.writeFileSync(OUTPUT_PDF, buffer);
  process.stdout.write(JSON.stringify({ ok: true, pdf: OUTPUT_PDF, json: OUTPUT_JSON }, null, 2));
}

render().catch((error) => {
  process.stderr.write(String(error?.stack || error));
  process.exit(1);
});
