/* global window */
// ============================================================================
// MELR · Banque islamique de développement (BID / IsDB) — RMF + PIAR export
// ----------------------------------------------------------------------------
// Génère un rapport de suivi au format .docx combinant les deux instruments
// de la BID : le RMF (Results Monitoring Framework), qui porte la chaîne de
// résultats et les indicateurs, et le PIAR (Project Implementation Assessment
// and Support Report), qui porte les notations et les actions d'appui.
//
// Structure générée :
//   A. Fiche projet
//   B. Alignement stratégique (stratégie de la BID et ODD)
//   C. Cadre de suivi des résultats (RMF) — Objectif / Effets / Produits
//   D. Notations de mise en œuvre (PIAR)
//   E. Modes de financement
//   F. Questions de mise en œuvre et actions d'appui
//   G. Durabilité et leçons apprises
//
// ⚠️ SPÉCIFICITÉ BID — MODES DE FINANCEMENT. La BID finance selon des modes
// conformes à la charia (Istisna'a, Ijara, Murabaha, vente à tempérament,
// Mudaraba restreinte). Le modèle de données MELR classe les sources en
// grant / debt / equity (exante_financing_sources.kind). La section E propose
// une CORRESPONDANCE INDICATIVE : le mode réel est une donnée contractuelle
// qui doit être saisie ou confirmée, jamais déduite automatiquement.
//
// ⚠️ La structure suit le cadre PUBLIC de la BID. Les libellés et la
// numérotation du formulaire officiel en vigueur doivent être confrontés au
// gabarit fourni par la Banque avant transmission.
//
// Point d'entrée : window.exportIsdbRmf({...})
// Utilise les primitives partagées de window.melrDonor.
// ============================================================================

(function () {
  if (typeof window === "undefined") return;

  const ISDB_GREEN = "12694A";   // vert institutionnel BID
  const ISDB_ACCENT = "9A7B23";  // or d'accentuation

  function _shared() { return window.melrDonor; }
  function _ok() { return !!(_shared() && _shared().isReady && _shared().isReady()); }

  // Correspondance INDICATIVE entre la typologie MELR et les modes de
  // financement de la BID. Volontairement non automatique : chaque ligne
  // porte la mention « à confirmer », car le mode est contractuel.
  function financingModes(lang) {
    const L = _shared().L;
    return [
      ["grant", L(lang, "Subvention", "Grant", "Subvención"),
       L(lang, "Don d'assistance technique · ressources Waqf",
              "Technical assistance grant · Waqf resources",
              "Donación de asistencia técnica · recursos Waqf")],
      ["debt", L(lang, "Dette / concours remboursable", "Debt / repayable financing", "Deuda / financiamiento reembolsable"),
       L(lang, "Istisna'a (construction) · Ijara (crédit-bail) · Murabaha · vente à tempérament",
              "Istisna'a (construction) · Ijara (leasing) · Murabaha · installment sale",
              "Istisna'a (construcción) · Ijara (arrendamiento) · Murabaha · venta a plazos")],
      ["equity", L(lang, "Fonds propres", "Equity", "Capital propio"),
       L(lang, "Participation au capital · Mudaraba restreinte",
              "Equity participation · restricted Mudaraba",
              "Participación en el capital · Mudaraba restringida")],
    ];
  }

  function avgPct(indicators, year, periods) {
    const s = _shared();
    const vals = [];
    (indicators || []).forEach((ind) => {
      const perf = s.computePerformance(ind, year, periods);
      const last = perf.pct[perf.pct.length - 1];
      if (last != null && isFinite(last)) vals.push(last);
    });
    if (!vals.length) return null;
    return Math.round(vals.reduce((a, b) => a + b, 0) / vals.length);
  }

  // Notation PIAR : échelle à 4 niveaux, dérivée du taux d'atteinte.
  function piarRating(pct, lang) {
    const L = _shared().L;
    if (pct == null) return { score: null, label: "—" };
    if (pct >= 95) return { score: 4, label: L(lang, "Très satisfaisant", "Highly satisfactory", "Muy satisfactorio") };
    if (pct >= 80) return { score: 3, label: L(lang, "Satisfaisant", "Satisfactory", "Satisfactorio") };
    if (pct >= 60) return { score: 2, label: L(lang, "Modérément satisfaisant", "Moderately satisfactory", "Moderadamente satisfactorio") };
    return { score: 1, label: L(lang, "Insatisfaisant", "Unsatisfactory", "Insatisfactorio") };
  }

  // ── Page de garde ──────────────────────────────────────────────────────
  function buildCover({ orgName, scopeLabel, year, lang }) {
    const { Paragraph, TextRun, AlignmentType } = window.docx;
    const s = _shared();
    const L = s.L;
    const C = (text, opts) => new Paragraph({
      alignment: AlignmentType.CENTER,
      spacing: { after: (opts && opts.after) || 200, before: (opts && opts.before) || 0 },
      children: [new TextRun({ text, ...(opts && opts.run ? opts.run : {}) })],
    });
    return [
      new Paragraph({ spacing: { before: 1200 }, children: [] }),
      C("Banque islamique de développement", { run: { bold: true, size: 46, color: ISDB_GREEN }, after: 60 }),
      C("Islamic Development Bank", { run: { italics: true, size: 22, color: s.COLORS.MUTED }, after: 500 }),
      C(L(lang, "Cadre de suivi des résultats et rapport d'exécution (RMF · PIAR)",
                "Results Monitoring Framework and Implementation Report (RMF · PIAR)",
                "Marco de seguimiento de resultados e informe de ejecución (RMF · PIAR)"),
        { run: { bold: true, size: 28, color: ISDB_GREEN }, after: 400 }),
      C(scopeLabel || L(lang, "Projet", "Project", "Proyecto"), { run: { bold: true, size: 28 } }),
      C(orgName || L(lang, "Organe d'exécution", "Implementing agency", "Organismo ejecutor"),
        { run: { size: 24, color: s.COLORS.MUTED } }),
      C(L(lang, "Période de référence", "Reporting period", "Período de referencia") + " : " + year,
        { run: { size: 22 }, before: 700 }),
      C(L(lang, "Document généré le ", "Generated on ", "Documento generado el ") +
        new Date().toLocaleDateString(window.L("fr-FR", "en-US", "es-ES")),
        { run: { size: 20, italics: true, color: s.COLORS.MUTED }, after: 1500 }),
      C(L(lang, "Généré automatiquement par MELR · REFT Africa",
                "Auto-generated by MELR · REFT Africa",
                "Generado automáticamente por MELR · REFT Africa"),
        { run: { size: 18, color: s.COLORS.MUTED } }),
    ];
  }

  // ── A. Fiche projet ────────────────────────────────────────────────────
  function buildProjectSheet({ projects, scopeLabel, orgName, year, lang }) {
    const s = _shared();
    const { H, P, Cell, Row, Tbl, Spacer } = s;
    const out = [];
    const p = (projects && projects[0]) || {};
    out.push(H(1, s.L(lang, "A. Fiche projet", "A. Project sheet", "A. Ficha del proyecto"), { color: ISDB_GREEN }));
    out.push(P(s.L(lang,
      "Cette fiche identifie l'opération et son cadre d'exécution. Elle sert d'en-tête de référence au RMF comme au PIAR.",
      "This sheet identifies the operation and its implementation framework. It serves as the reference header for both the RMF and the PIAR.",
      "Esta ficha identifica la operación y su marco de ejecución. Sirve de encabezado de referencia tanto para el RMF como para el PIAR.")));
    const row = (k, v) => Row([
      Cell(k, { width: 3200, bold: true, size: 20, fill: "F1F6F3" }),
      Cell(v || "—", { width: 6160, size: 20 }),
    ]);
    out.push(Tbl([
      row(s.L(lang, "Intitulé du projet", "Project title", "Título del proyecto"), scopeLabel),
      row(s.L(lang, "Organe d'exécution", "Executing agency", "Organismo ejecutor"), orgName),
      row(s.L(lang, "Code / référence", "Code / reference", "Código / referencia"), p.code),
      row(s.L(lang, "Secteur", "Sector", "Sector"), p.sector),
      row(s.L(lang, "Pays membre", "Member country", "País miembro"), p.country),
      row(s.L(lang, "Période de référence", "Reporting period", "Período de referencia"), String(year)),
      row(s.L(lang, "Mode de financement", "Financing mode", "Modo de financiamiento"),
          s.L(lang, "À confirmer — voir section E", "To be confirmed — see section E", "Por confirmar — véase la sección E")),
    ], { columnWidths: [3200, 6160] }));
    out.push(Spacer());
    return out;
  }

  // ── B. Alignement stratégique ──────────────────────────────────────────
  function buildAlignment({ lang }) {
    const s = _shared();
    const { H, P, Cell, Row, Tbl, Spacer } = s;
    const out = [];
    out.push(H(1, s.L(lang, "B. Alignement stratégique", "B. Strategic alignment", "B. Alineación estratégica"), { color: ISDB_GREEN }));
    out.push(P(s.L(lang,
      "La BID apprécie chaque opération au regard de sa contribution à sa stratégie institutionnelle et aux objectifs de développement durable. Le tableau ci-dessous établit ce rattachement.",
      "IsDB assesses each operation against its contribution to the institutional strategy and to the sustainable development goals. The table below establishes that linkage.",
      "El BID evalúa cada operación según su contribución a la estrategia institucional y a los objetivos de desarrollo sostenible. El cuadro siguiente establece esa vinculación.")));
    const th = (t, w) => Cell(t, { width: w, bold: true, fill: ISDB_GREEN, color: "FFFFFF", size: 18 });
    out.push(Tbl([
      Row([
        th(s.L(lang, "Axe d'alignement", "Alignment dimension", "Eje de alineación"), 4200),
        th(s.L(lang, "Rattachement du projet", "Project linkage", "Vinculación del proyecto"), 5160),
      ]),
      Row([Cell(s.L(lang, "Priorité de la stratégie de la BID", "IsDB strategy priority", "Prioridad de la estrategia del BID"), { width: 4200, bold: true }), Cell("", { width: 5160 })]),
      Row([Cell(s.L(lang, "Objectifs de développement durable visés", "Targeted sustainable development goals", "Objetivos de desarrollo sostenible perseguidos"), { width: 4200, bold: true }), Cell("", { width: 5160 })]),
      Row([Cell(s.L(lang, "Stratégie sectorielle nationale", "National sector strategy", "Estrategia sectorial nacional"), { width: 4200, bold: true }), Cell("", { width: 5160 })]),
      Row([Cell(s.L(lang, "Contribution à la coopération Sud-Sud", "Contribution to South-South cooperation", "Contribución a la cooperación Sur-Sur"), { width: 4200, bold: true }), Cell("", { width: 5160 })]),
    ], { columnWidths: [4200, 5160] }));
    out.push(Spacer());
    return out;
  }

  // ── C. Cadre de suivi des résultats (RMF) ──────────────────────────────
  function buildRmf({ indicators, year, lang, periods }) {
    const s = _shared();
    const { H, P, Cell, Row, Tbl, Spacer } = s;
    const out = [];
    out.push(H(1, s.L(lang, "C. Cadre de suivi des résultats (RMF)",
                            "C. Results Monitoring Framework (RMF)",
                            "C. Marco de seguimiento de resultados (RMF)"), { color: ISDB_GREEN }));
    out.push(P(s.L(lang,
      "Le RMF présente la chaîne de résultats de l'opération. Chaque indicateur y figure avec sa référence, sa cible, sa valeur atteinte et son taux d'atteinte sur les périodes suivies.",
      "The RMF sets out the operation's results chain. Each indicator appears with its baseline, target, actual value and achievement rate over the tracked periods.",
      "El RMF presenta la cadena de resultados de la operación. Cada indicador figura con su línea de base, meta, valor alcanzado y tasa de logro en los períodos seguidos.")));

    const bag = s.groupByLevel(indicators);
    const levels = [
      ["Impact", s.L(lang, "Objectif / Impact", "Goal / Impact", "Objetivo / Impacto")],
      ["Outcome", s.L(lang, "Effets", "Outcomes", "Efectos")],
      ["Output", s.L(lang, "Produits", "Outputs", "Productos")],
    ];
    const Y = periods;

    levels.forEach(([key, label]) => {
      const list = bag[key] || [];
      if (!list.length) return;
      out.push(H(2, label, { color: ISDB_ACCENT }));
      const header = [
        Cell(s.L(lang, "Code", "Code", "Código"), { width: 800, bold: true, fill: ISDB_GREEN, color: "FFFFFF", size: 18 }),
        Cell(s.L(lang, "Indicateur", "Indicator", "Indicador"), { width: 2600, bold: true, fill: ISDB_GREEN, color: "FFFFFF", size: 18 }),
        Cell(s.L(lang, "Unité", "Unit", "Unidad"), { width: 600, bold: true, fill: ISDB_GREEN, color: "FFFFFF", size: 18 }),
        Cell(s.L(lang, "Réf.", "Base.", "Ref."), { width: 800, bold: true, fill: ISDB_GREEN, color: "FFFFFF", size: 18 }),
      ];
      const perf0 = s.computePerformance(list[0], year, Y);
      for (let i = 0; i < Y; i++) {
        header.push(Cell(perf0.years[i] + " " + s.L(lang, "cible", "target", "meta"), { width: 800, bold: true, fill: ISDB_GREEN, color: "FFFFFF", size: 16 }));
        header.push(Cell(perf0.years[i] + " " + s.L(lang, "réel", "actual", "real"), { width: 800, bold: true, fill: ISDB_GREEN, color: "FFFFFF", size: 16 }));
        header.push(Cell("%", { width: 520, bold: true, fill: ISDB_GREEN, color: "FFFFFF", size: 16 }));
      }
      const rows = [Row(header)];
      list.forEach((ind) => rows.push(s.iptRow(ind, s.computePerformance(ind, year, Y), lang, Y)));
      out.push(Tbl(rows));
      out.push(Spacer());
    });

    if (!(indicators || []).length) {
      out.push(P(s.L(lang, "Aucun indicateur n'est rattaché au périmètre sélectionné.",
                           "No indicator is attached to the selected scope.",
                           "Ningún indicador está vinculado al alcance seleccionado."),
        { run: { italics: true, color: s.COLORS.MUTED } }));
    }
    return out;
  }

  // ── D. Notations PIAR ──────────────────────────────────────────────────
  function buildPiar({ indicators, year, lang, periods }) {
    const s = _shared();
    const { H, P, Cell, Row, Tbl, Spacer } = s;
    const out = [];
    out.push(H(1, s.L(lang, "D. Notations de mise en œuvre (PIAR)",
                            "D. Implementation ratings (PIAR)",
                            "D. Calificaciones de ejecución (PIAR)"), { color: ISDB_GREEN }));
    out.push(P(s.L(lang,
      "Le PIAR apprécie l'exécution de l'opération et déclenche, le cas échéant, les mesures d'appui de la Banque. Les notes proposées ci-dessous sont dérivées des taux d'atteinte mesurés dans MELR.",
      "The PIAR assesses implementation and, where needed, triggers the Bank's support measures. The ratings proposed below are derived from the achievement rates measured in MELR.",
      "El PIAR evalúa la ejecución y, en su caso, activa las medidas de apoyo del Banco. Las calificaciones propuestas abajo se derivan de las tasas de logro medidas en MELR.")));

    const bag = s.groupByLevel(indicators);
    const rOut = piarRating(avgPct(bag.Output, year, periods), lang);
    const rEff = piarRating(avgPct(bag.Outcome, year, periods), lang);
    const rAll = piarRating(avgPct(indicators, year, periods), lang);
    const th = (t, w) => Cell(t, { width: w, bold: true, fill: ISDB_GREEN, color: "FFFFFF", size: 18 });
    const line = (label, r, fill) => Row([
      Cell(label, { width: 4200, bold: true, fill }),
      Cell(r.score == null ? "—" : String(r.score), { width: 1600, bold: true, fill }),
      Cell(r.label, { width: 3560, fill }),
    ]);
    out.push(Tbl([
      Row([
        th(s.L(lang, "Dimension", "Dimension", "Dimensión"), 4200),
        th(s.L(lang, "Note", "Rating", "Calificación"), 1600),
        th(s.L(lang, "Appréciation", "Assessment", "Apreciación"), 3560),
      ]),
      line(s.L(lang, "Avancement des produits", "Output progress", "Avance de los productos"), rOut),
      line(s.L(lang, "Atteinte des effets", "Outcome achievement", "Logro de los efectos"), rEff),
      line(s.L(lang, "Appréciation d'ensemble", "Overall assessment", "Apreciación general"), rAll, "F1F6F3"),
    ], { columnWidths: [4200, 1600, 3560] }));
    out.push(P(s.L(lang,
      "Échelle et seuils d'atteinte : 4 très satisfaisant (≥ 95 %) · 3 satisfaisant (80 – 94 %) · 2 modérément satisfaisant (60 – 79 %) · 1 insatisfaisant (< 60 %). Les notes sont dérivées du taux d'atteinte moyen des indicateurs ; elles constituent un point de départ traçable que le chargé d'opération peut corriger.",
      "Scale and achievement thresholds: 4 highly satisfactory (≥ 95 %) · 3 satisfactory (80 – 94 %) · 2 moderately satisfactory (60 – 79 %) · 1 unsatisfactory (< 60 %). Ratings are derived from the average indicator achievement rate; they are a traceable starting point the task manager may adjust.",
      "Escala y umbrales de logro: 4 muy satisfactorio (≥ 95 %) · 3 satisfactorio (80 – 94 %) · 2 moderadamente satisfactorio (60 – 79 %) · 1 insatisfactorio (< 60 %). Las calificaciones se derivan de la tasa media de logro; son un punto de partida trazable que el responsable puede ajustar."),
      { run: { italics: true, color: s.COLORS.MUTED, size: 18 } }));
    out.push(Spacer());
    return out;
  }

  // ── E. Modes de financement ────────────────────────────────────────────
  function buildFinancing({ lang }) {
    const s = _shared();
    const { H, P, Cell, Row, Tbl, Spacer } = s;
    const out = [];
    out.push(H(1, s.L(lang, "E. Modes de financement", "E. Financing modes", "E. Modos de financiamiento"), { color: ISDB_GREEN }));
    out.push(P(s.L(lang,
      "La BID finance selon des modes conformes à la charia, dont la typologie diffère de la classification usuelle en subvention, dette et fonds propres. Le tableau ci-dessous propose une correspondance indicative entre les catégories enregistrées dans MELR et les modes de la Banque.",
      "IsDB finances through Sharia-compliant modes, whose taxonomy differs from the usual grant, debt and equity classification. The table below proposes an indicative correspondence between the categories recorded in MELR and the Bank's modes.",
      "El BID financia mediante modos conformes a la sharía, cuya tipología difiere de la clasificación usual en subvención, deuda y capital propio. El cuadro siguiente propone una correspondencia indicativa entre las categorías registradas en MELR y los modos del Banco.")));
    const th = (t, w) => Cell(t, { width: w, bold: true, fill: ISDB_GREEN, color: "FFFFFF", size: 18 });
    const rows = [Row([
      th(s.L(lang, "Catégorie MELR", "MELR category", "Categoría MELR"), 2600),
      th(s.L(lang, "Libellé", "Label", "Etiqueta"), 2400),
      th(s.L(lang, "Modes BID correspondants", "Corresponding IsDB modes", "Modos BID correspondientes"), 4360),
    ])];
    financingModes(lang).forEach(([key, label, modes]) => {
      rows.push(Row([
        Cell(key, { width: 2600, bold: true, size: 18 }),
        Cell(label, { width: 2400, size: 18 }),
        Cell(modes, { width: 4360, size: 18 }),
      ]));
    });
    out.push(Tbl(rows, { columnWidths: [2600, 2400, 4360] }));
    out.push(P(s.L(lang,
      "⚠️ Correspondance indicative. Le mode de financement est une donnée contractuelle : il doit être confirmé à partir de l'accord de financement et ne peut être déduit automatiquement de la catégorie enregistrée dans MELR.",
      "⚠️ Indicative correspondence. The financing mode is contractual data: it must be confirmed from the financing agreement and cannot be inferred automatically from the category recorded in MELR.",
      "⚠️ Correspondencia indicativa. El modo de financiamiento es un dato contractual: debe confirmarse a partir del acuerdo de financiamiento y no puede deducirse automáticamente de la categoría registrada en MELR."),
      { run: { italics: true, color: s.COLORS.MUTED, size: 18 } }));
    out.push(Spacer());
    return out;
  }

  // ── F. Questions et actions d'appui ────────────────────────────────────
  function buildIssues({ lang }) {
    const s = _shared();
    const { H, P, Cell, Row, Tbl, Spacer } = s;
    const out = [];
    out.push(H(1, s.L(lang, "F. Questions de mise en œuvre et actions d'appui",
                            "F. Implementation issues and support actions",
                            "F. Cuestiones de ejecución y acciones de apoyo"), { color: ISDB_GREEN }));
    out.push(P(s.L(lang,
      "Le PIAR ne se limite pas au constat : il engage la Banque sur des mesures d'appui. Chaque question ouverte est donc assortie d'une action, d'un responsable et d'une échéance.",
      "The PIAR is not limited to observation: it commits the Bank to support measures. Each open issue therefore carries an action, an owner and a deadline.",
      "El PIAR no se limita a la constatación: compromete al Banco con medidas de apoyo. Cada cuestión abierta lleva por tanto una acción, un responsable y un plazo.")));
    const th = (t, w) => Cell(t, { width: w, bold: true, fill: ISDB_GREEN, color: "FFFFFF", size: 18 });
    out.push(Tbl([
      Row([
        th(s.L(lang, "Question / difficulté", "Issue", "Cuestión / dificultad"), 3200),
        th(s.L(lang, "Action d'appui", "Support action", "Acción de apoyo"), 3200),
        th(s.L(lang, "Responsable", "Owner", "Responsable"), 1600),
        th(s.L(lang, "Échéance", "Deadline", "Plazo"), 1360),
      ]),
      Row([Cell("", { width: 3200 }), Cell("", { width: 3200 }), Cell("", { width: 1600 }), Cell("", { width: 1360 })]),
      Row([Cell("", { width: 3200 }), Cell("", { width: 3200 }), Cell("", { width: 1600 }), Cell("", { width: 1360 })]),
      Row([Cell("", { width: 3200 }), Cell("", { width: 3200 }), Cell("", { width: 1600 }), Cell("", { width: 1360 })]),
    ], { columnWidths: [3200, 3200, 1600, 1360] }));
    out.push(P(s.L(lang, "(À compléter à partir du module Risques de MELR.)",
                         "(To be completed from the MELR Risks module.)",
                         "(A completar a partir del módulo de Riesgos de MELR.)"),
      { run: { italics: true, color: s.COLORS.MUTED, size: 18 } }));
    out.push(Spacer());
    return out;
  }

  // ── G. Durabilité et leçons ────────────────────────────────────────────
  function buildSustainability({ lang }) {
    const s = _shared();
    const { H, P } = s;
    const out = [];
    out.push(H(1, s.L(lang, "G. Durabilité et leçons apprises",
                            "G. Sustainability and lessons learned",
                            "G. Sostenibilidad y lecciones aprendidas"), { color: ISDB_GREEN }));
    out.push(P(s.L(lang,
      "La BID accorde une attention particulière à la pérennité des acquis après l'achèvement. Les éléments ci-dessous alimentent le rapport d'achèvement.",
      "IsDB pays particular attention to the durability of results after completion. The elements below feed the completion report.",
      "El BID presta especial atención a la perdurabilidad de los logros tras la terminación. Los elementos siguientes alimentan el informe de terminación.")));
    [
      s.L(lang, "Dispositif d'exploitation et d'entretien après achèvement", "Operation and maintenance arrangements after completion", "Dispositivo de operación y mantenimiento tras la terminación"),
      s.L(lang, "Capacités transférées à l'organe d'exécution", "Capacities transferred to the executing agency", "Capacidades transferidas al organismo ejecutor"),
      s.L(lang, "Appropriation par les bénéficiaires", "Ownership by beneficiaries", "Apropiación por los beneficiarios"),
      s.L(lang, "Enseignements pour les opérations suivantes", "Lessons for subsequent operations", "Lecciones para operaciones posteriores"),
    ].forEach((t) => out.push(P("• " + t, { run: { size: 22 } })));
    out.push(P(s.L(lang, "(À compléter à partir du module Apprentissage de MELR.)",
                         "(To be completed from the MELR Learning module.)",
                         "(A completar a partir del módulo de Aprendizaje de MELR.)"),
      { run: { italics: true, color: s.COLORS.MUTED } }));
    return out;
  }

  // ── Assemblage ─────────────────────────────────────────────────────────
  function buildDoc({ projects, indicators, activities, stakeholders, donorId, donorLabel, currency, year, scopeLabel, orgName, lang, periods }) {
    if (!_ok()) throw new Error("melrDonor shared module not loaded");
    const { Document, Footer, PageNumber, TextRun, Paragraph, AlignmentType } = window.docx;
    const s = _shared();
    const children = [];
    children.push(...buildCover({ orgName, scopeLabel, year, lang }));
    children.push(s.PageBreak());
    children.push(...buildProjectSheet({ projects, scopeLabel, orgName, year, lang }));
    children.push(...buildAlignment({ lang }));
    children.push(...buildRmf({ indicators, year, lang, periods }));
    // Activites du PTBA financees par la Banque : montants saisis source par
    // source, donc aucun prorata. Meme section partagee que les autres bailleurs.
    if (s.buildActivitySection && (activities || []).length) {
      children.push(...s.buildActivitySection({
        activities, stakeholders, donorId, donorLabel: donorLabel || "la BID",
        lang, color: ISDB_GREEN, currency,
        title: s.L(lang, "C-bis. Activites du PTBA financees par la Banque",
                         "C-bis. Work plan activities financed by the Bank",
                         "C-bis. Actividades del plan financiadas por el Banco"),
      }));
    }
    children.push(...buildPiar({ indicators, year, lang, periods }));
    children.push(...buildFinancing({ lang }));
    children.push(...buildIssues({ lang }));
    children.push(...buildSustainability({ lang }));
    return new Document({
      creator: "MELR",
      title: "IsDB RMF/PIAR — " + (scopeLabel || "Project") + " — " + year,
      description: "IsDB Results Monitoring Framework and PIAR auto-generated by MELR",
      styles: { default: { document: { run: { font: "Calibri", size: 22 } } } },
      sections: [{
        properties: { page: { margin: { top: 1200, right: 1200, bottom: 1200, left: 1200 } } },
        footers: {
          default: new Footer({
            children: [new Paragraph({
              alignment: AlignmentType.CENTER,
              children: [
                new TextRun({ text: "BID · RMF/PIAR · " + (scopeLabel || "Projet") + " · " + year + " · ", color: s.COLORS.MUTED, size: 18 }),
                new TextRun({ children: [PageNumber.CURRENT], color: s.COLORS.MUTED, size: 18 }),
                new TextRun({ text: " / ", color: s.COLORS.MUTED, size: 18 }),
                new TextRun({ children: [PageNumber.TOTAL_PAGES], color: s.COLORS.MUTED, size: 18 }),
              ],
            })],
          }),
        },
        children,
      }],
    });
  }

  async function exportIsdbRmf(args) {
    args = args || {};
    if (!_ok()) { alert((args.lang || "fr") === "fr" ? "Module partagé indisponible." : "Shared module unavailable."); return; }
    const s = _shared();
    try {
      const year = args.year || new Date().getFullYear();
      const doc = buildDoc({
        projects: args.projects || [],
        indicators: args.indicators || [],
        activities: args.activities || [],
        stakeholders: args.stakeholders || null,
        donorId: args.fundingSourceId || null,
        donorLabel: args.fundingSourceLabel || null,
        currency: args.currency || "XOF",
        year,
        scopeLabel: args.scopeLabel || s.L(args.lang, "Projet", "Project", "Proyecto"),
        orgName: args.orgName || "",
        lang: args.lang || "fr",
        periods: args.periods || 3,
      });
      await s.saveDocx(doc, (args.filename || ("BID-RMF-" + year)), args.lang);
    } catch (e) {
      console.error("[IsDB export]", e);
      alert(((args.lang || "fr") === "fr" ? "Erreur BID : " : "IsDB error: ") + e.message);
    }
  }
  window.exportIsdbRmf = exportIsdbRmf;
})();
