/* global window */
// ============================================================================
// MELR · GAVI Performance Framework export
// ----------------------------------------------------------------------------
// Generates a GAVI Alliance Performance Framework as a .docx file.
//
// GAVI (Global Alliance for Vaccines and Immunisation) is the second
// largest health donor in low-income Africa. Implementing partners must
// produce annual performance frameworks aligned with the country's cMYP /
// HSCC plan, broken down by routine immunization, HSS, supply chain,
// surveillance, demand creation, and sustainable financing.
//
// Generated structure :
//   1. Cover Page (GAVI branding)
//   2. Country Context & Immunization Profile
//        - Coverage baseline (DTP3, MCV1, MCV2, BCG)
//        - Dropout rate, equity, stockouts
//   3. Strategic Objectives
//   4. Performance Framework table (IPTT-style, 3 FY)
//   5. Programme Components
//        - Routine immunization
//        - HSS (Health Systems Strengthening)
//        - Supply chain & cold chain
//        - Surveillance
//        - Demand creation & community engagement
//        - Financial sustainability
//   6. Monitoring & Evaluation Plan
//   7. Risk register
//
// Entry point :
//   await window.exportGaviFramework({ projects, indicators, scope, year,
//                                       scopeLabel, orgName, lang })
//
// Uses shared helpers from window.melrDonor (reporting-donor-shared.jsx).
// ============================================================================

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

  // GAVI brand color (their teal/turquoise used in official PDFs)
  const GAVI_COLOR = "1B6F8F";

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

  // ── Cover Page ──────────────────────────────────────────────────────────
  function buildCover({ orgName, scopeLabel, year, lang }) {
    const { Paragraph, TextRun, AlignmentType } = window.docx;
    const L = _shared().L;
    return [
      new Paragraph({ spacing: { before: 1200 }, children: [] }),
      new Paragraph({
        alignment: AlignmentType.CENTER,
        children: [new TextRun({ text: "GAVI Alliance", bold: true, size: 56, color: GAVI_COLOR })],
      }),
      new Paragraph({
        alignment: AlignmentType.CENTER,
        spacing: { after: 600 },
        children: [new TextRun({ text: L(lang, "Cadre de performance — Vaccination & HSS", "Performance Framework — Immunization & HSS", "Marco de desempeño — Vacunación y HSS"), bold: true, size: 32, color: GAVI_COLOR })],
      }),
      new Paragraph({
        alignment: AlignmentType.CENTER,
        spacing: { after: 200 },
        children: [new TextRun({ text: scopeLabel || L(lang, "Programme national de vaccination", "National immunization programme", "Programa nacional de vacunación"), bold: true, size: 28 })],
      }),
      new Paragraph({
        alignment: AlignmentType.CENTER,
        spacing: { after: 200 },
        children: [new TextRun({ text: orgName || L(lang, "Pays / Organisation bénéficiaire", "Country / Implementing organization", "País / Organización beneficiaria"), size: 24, color: _shared().COLORS.MUTED })],
      }),
      new Paragraph({
        alignment: AlignmentType.CENTER,
        spacing: { before: 800, after: 200 },
        children: [new TextRun({ text: L(lang, "Année de référence", "Reference year", "Año de referencia") + " : " + year, size: 22 })],
      }),
      new Paragraph({
        alignment: AlignmentType.CENTER,
        spacing: { after: 1600 },
        children: [new TextRun({ text: L(lang, "Document généré le ", "Generated on ", "Documento generado el ") + new Date().toLocaleDateString(window.L("fr-FR", "en-US", "es-ES")), size: 20, color: _shared().COLORS.MUTED, italics: true })],
      }),
      new Paragraph({
        alignment: AlignmentType.CENTER,
        children: [new TextRun({ text: L(lang, "Généré automatiquement par MELR · REFT Africa", "Auto-generated by MELR · REFT Africa", "Generado automáticamente por MELR · REFT Africa"), size: 18, color: _shared().COLORS.MUTED })],
      }),
    ];
  }

  // ── Country Context & Immunization Profile ─────────────────────────────
  function buildCountryContext({ projects, indicators, scopeLabel, lang }) {
    const s = _shared();
    const { H, P, Cell, Row, Tbl, Spacer, PageBreak } = s;
    const out = [];
    out.push(H(1, s.L(lang, "1. Contexte pays & profil de vaccination", "1. Country Context & Immunization Profile", "1. Contexto del país y perfil de vacunación"), { color: GAVI_COLOR }));
    out.push(P(s.L(lang,
      "Cette section décrit le contexte épidémiologique national, le profil de couverture vaccinale et les principales inégalités observées. Les indicateurs présentés ici servent de base au cadre de performance.",
      "This section describes the national epidemiological context, immunization coverage profile, and major inequities observed. Indicators here form the baseline for the performance framework.", "Esta sección describe el contexto epidemiológico nacional, el perfil de cobertura vacunal y las principales desigualdades observadas. Los indicadores presentados aquí sirven de base al marco de desempeño.")));

    out.push(H(2, s.L(lang, "Couvertures vaccinales — base de référence", "Vaccination coverage — baseline", "Coberturas vacunales — línea de base"), { color: GAVI_COLOR }));
    out.push(P(s.L(lang,
      "Les couvertures officielles WHO/UNICEF Estimates of National Immunization Coverage (WUENIC) sont à confronter aux mesures terrain. Les indicateurs ci-dessous extraits de MELR retracent les performances mesurées sur les projets du périmètre.",
      "Official WHO/UNICEF Estimates of National Immunization Coverage (WUENIC) should be cross-checked against field measurements. The indicators below extracted from MELR show measured performance across in-scope projects.", "Las coberturas oficiales WHO/UNICEF Estimates of National Immunization Coverage (WUENIC) deben contrastarse con las mediciones de terreno. Los indicadores que figuran a continuación, extraídos de MELR, reflejan el desempeño medido en los proyectos del ámbito.")));

    const hdr = { bold: true, color: "FFFFFF", fill: GAVI_COLOR };
    const headerRow = Row([
      Cell(s.L(lang, "Indicateur", "Indicator", "Indicador"),    { ...hdr, width: 3000 }),
      Cell(s.L(lang, "Référence", "Baseline", "Línea de base"),     { ...hdr, width: 1400, align: window.docx.AlignmentType.CENTER }),
      Cell(s.L(lang, "Cible", "Target", "Meta"),           { ...hdr, width: 1400, align: window.docx.AlignmentType.CENTER }),
      Cell(s.L(lang, "Réalisé", "Actual", "Realizado"),         { ...hdr, width: 1400, align: window.docx.AlignmentType.CENTER }),
      Cell(s.L(lang, "Unité", "Unit", "Unidad"),             { ...hdr, width: 800,  align: window.docx.AlignmentType.CENTER }),
      Cell(s.L(lang, "Niveau", "Level", "Nivel"),           { ...hdr, width: 1360, align: window.docx.AlignmentType.CENTER }),
    ]);
    const rows = [headerRow];
    (indicators || []).forEach((i) => {
      rows.push(Row([
        Cell(lang === "fr" ? (i.name_fr || i.name) : (i.name_en || i.name), { width: 3000, size: 18 }),
        Cell(s.fmtNum(i.baseline, i.unit), { width: 1400, size: 18, align: window.docx.AlignmentType.CENTER }),
        Cell(s.fmtNum(i.target, i.unit),   { width: 1400, size: 18, align: window.docx.AlignmentType.CENTER }),
        Cell(s.fmtNum(i.actual, i.unit),   { width: 1400, size: 18, align: window.docx.AlignmentType.CENTER }),
        Cell(i.unit || "—",                { width: 800,  size: 18, align: window.docx.AlignmentType.CENTER }),
        Cell(i.level || "Output",          { width: 1360, size: 18, align: window.docx.AlignmentType.CENTER }),
      ]));
    });
    if ((indicators || []).length === 0) {
      rows.push(Row([Cell(s.L(lang, "Aucun indicateur dans le périmètre", "No indicators in scope", "Ningún indicador en el perímetro"), { colSpan: 6, color: s.COLORS.MUTED, align: window.docx.AlignmentType.CENTER })]));
    }
    out.push(Tbl(rows, { columnWidths: [3000, 1400, 1400, 1400, 800, 1360] }));
    out.push(Spacer());

    out.push(H(2, s.L(lang, "Projets contributifs", "Contributing projects", "Proyectos contribuyentes"), { color: GAVI_COLOR }));
    const projHdr = Row([
      Cell(s.L(lang, "Code", "Code"),       { ...hdr, width: 1200 }),
      Cell(s.L(lang, "Nom", "Name", "Nombre"),        { ...hdr, width: 4200 }),
      Cell(s.L(lang, "Pays", "Country", "País"),    { ...hdr, width: 1800 }),
      Cell(s.L(lang, "Phase", "Phase"),     { ...hdr, width: 2160 }),
    ]);
    const projRows = [projHdr].concat((projects || []).map((p) =>
      Row([
        Cell(p.id || p.code || "—",                                                 { width: 1200, size: 18 }),
        Cell(p.nameFr || p.name_fr || p.name || "—",                                { width: 4200, size: 18 }),
        Cell((p.countries || [p.country]).filter(Boolean).join(", ") || "—",        { width: 1800, size: 18 }),
        Cell(p.phase || p.status || "—",                                            { width: 2160, size: 18 }),
      ])
    ));
    if ((projects || []).length === 0) {
      projRows.push(Row([Cell(s.L(lang, "Aucun projet dans le périmètre", "No project in scope", "Ningún proyecto en el perímetro"), { colSpan: 4, color: s.COLORS.MUTED, align: window.docx.AlignmentType.CENTER })]));
    }
    out.push(Tbl(projRows, { columnWidths: [1200, 4200, 1800, 2160] }));
    out.push(Spacer());

    return out;
  }

  // ── Strategic Objectives ───────────────────────────────────────────────
  function buildStrategicObjectives({ lang }) {
    const s = _shared();
    const { H, P, PageBreak } = s;
    const out = [];
    out.push(PageBreak());
    out.push(H(1, s.L(lang, "2. Objectifs stratégiques", "2. Strategic Objectives", "2. Objetivos estratégicos"), { color: GAVI_COLOR }));

    const objs = [
      { fr: "Augmenter durablement la couverture vaccinale (DTP3, MCV1, MCV2) dans tous les districts.",
        en: "Sustainably increase vaccination coverage (DTP3, MCV1, MCV2) across all districts.",
        es: "Aumentar de forma sostenible la cobertura de vacunación (DTP3, MCV1, MCV2) en todos los distritos." },
      { fr: "Réduire les inégalités d'accès (genre, géographie, statut socio-économique).",
        en: "Reduce access inequities (gender, geography, socio-economic status).",
        es: "Reducir las inequidades de acceso (género, geografía, situación socioeconómica)." },
      { fr: "Renforcer la chaîne d'approvisionnement et réduire les ruptures de stock à moins de 5 %.",
        en: "Strengthen the supply chain and reduce stockouts to under 5 %.",
        es: "Fortalecer la cadena de suministro y reducir los desabastecimientos a menos del 5 %." },
      { fr: "Améliorer la surveillance épidémiologique des MPVE (rougeole, polio, fièvre jaune, méningite).",
        en: "Improve epidemiological surveillance of VPDs (measles, polio, yellow fever, meningitis).",
        es: "Mejorar la vigilancia epidemiológica de las MPVE (sarampión, polio, fiebre amarilla, meningitis)." },
      { fr: "Mobiliser la communauté pour réduire le taux d'abandon (DTP1-DTP3 dropout) à moins de 10 %.",
        en: "Mobilize the community to reduce the dropout rate (DTP1-DTP3) to under 10 %.",
        es: "Movilizar a la comunidad para reducir la tasa de abandono (DTP1-DTP3) a menos del 10 %." },
      { fr: "Mettre en place une trajectoire de transition vers le financement domestique de la vaccination.",
        en: "Implement a transition pathway towards domestic financing of immunization.",
        es: "Establecer una trayectoria de transición hacia el financiamiento doméstico de la vacunación." },
    ];
    objs.forEach((o, i) => {
      out.push(P((i + 1) + ". " + s.L(lang, o.fr, o.en), { run: { size: 22 } }));
    });
    return out;
  }

  // ── Performance Framework (IPTT-style) ─────────────────────────────────
  function buildPerformanceFramework({ indicators, year, lang }) {
    const s = _shared();
    const { H, P, Cell, Row, Tbl, PageBreak } = s;
    const Y = 3;
    const out = [];
    out.push(PageBreak());
    out.push(H(1, s.L(lang, "3. Cadre de performance (Performance Framework)", "3. Performance Framework", "3. Marco de desempeño (Performance Framework)"), { color: GAVI_COLOR }));
    out.push(P(s.L(lang,
      "Le cadre de performance consolide indicateurs, cibles et réalisés sur trois années fiscales successives. Le code couleur RAG (rouge / ambre / vert) signale les performances respectivement < 70 %, 70-89 % et ≥ 90 % par rapport à la cible.",
      "The performance framework consolidates indicators, targets, and actuals across three successive fiscal years. The RAG color code (red / amber / green) flags performance respectively < 70 %, 70-89 %, and ≥ 90 % against target.", "El marco de desempeño consolida indicadores, metas y realizados a lo largo de tres años fiscales sucesivos. El código de colores RAG (rojo / ámbar / verde) señala el desempeño respectivamente < 70 %, 70-89 % y ≥ 90 % con respecto a la meta.")));

    const baseYear = parseInt(year, 10) || new Date().getFullYear();
    const yLabels = [];
    for (let i = 1; i <= Y; i++) yLabels.push("FY" + (baseYear - Y + i));

    const hdr = { bold: true, color: "FFFFFF", fill: GAVI_COLOR };
    const headerCells = [
      Cell(s.L(lang, "Code", "Code"),                  { ...hdr, width: 800 }),
      Cell(s.L(lang, "Indicateur", "Indicator", "Indicador"),       { ...hdr, width: 2600 }),
      Cell(s.L(lang, "Unité", "Unit", "Unidad"),                 { ...hdr, width: 600 }),
      Cell(s.L(lang, "Base", "Baseline", "Línea de base"),              { ...hdr, width: 800 }),
    ];
    yLabels.forEach((yl) => {
      headerCells.push(Cell(yl + " " + s.L(lang, "Cible", "Target", "Meta"),  { ...hdr, width: 800, align: window.docx.AlignmentType.CENTER }));
      headerCells.push(Cell(yl + " " + s.L(lang, "Réal.", "Actual", "Real."),  { ...hdr, width: 800, align: window.docx.AlignmentType.CENTER }));
      headerCells.push(Cell("%", { ...hdr, width: 520, align: window.docx.AlignmentType.CENTER }));
    });

    const rows = [Row(headerCells)];
    (indicators || []).forEach((ind) => {
      const perf = s.computePerformance(ind, baseYear, Y);
      rows.push(s.iptRow(ind, perf, lang, Y));
    });
    if ((indicators || []).length === 0) {
      rows.push(Row([Cell(s.L(lang, "Aucun indicateur dans le périmètre", "No indicators in scope", "Ningún indicador en el perímetro"),
        { colSpan: 4 + 3 * Y, color: s.COLORS.MUTED, align: window.docx.AlignmentType.CENTER })]));
    }

    const widths = [800, 2600, 600, 800];
    for (let i = 0; i < Y; i++) widths.push(800, 800, 520);
    out.push(Tbl(rows, { columnWidths: widths, width: widths.reduce((a, b) => a + b, 0) }));

    return out;
  }

  // ── Programme Components ───────────────────────────────────────────────
  function buildProgrammeComponents({ lang }) {
    const s = _shared();
    const { H, P, PageBreak } = s;
    const out = [];
    out.push(PageBreak());
    out.push(H(1, s.L(lang, "4. Composantes du programme", "4. Programme Components", "4. Componentes del programa"), { color: GAVI_COLOR }));

    const comps = [
      {
        h_fr: "4.1 Vaccination de routine",
        h_en: "4.1 Routine Immunization", h_es: "4.1 Vacunación de rutina",
        p_fr: "Calendrier vaccinal du Programme Élargi de Vaccination (PEV), accès aux sites de vaccination, micro-planification par district, sessions fixes et mobiles, gestion du registre. Objectif transversal : atteindre les enfants zéro-dose.",
        p_en: "Expanded Programme on Immunization (EPI) schedule, access to vaccination sites, district micro-planning, fixed and mobile sessions, register management. Cross-cutting goal: reach zero-dose children.", p_es: "Calendario de vacunación del Programa Ampliado de Inmunización (PAI), acceso a los puntos de vacunación, microplanificación por distrito, sesiones fijas y móviles, gestión del registro. Objetivo transversal: alcanzar a los niños con dosis cero.",
      },
      {
        h_fr: "4.2 Renforcement des systèmes de santé (HSS)",
        h_en: "4.2 Health Systems Strengthening (HSS)", h_es: "4.2 Fortalecimiento de los sistemas de salud (HSS)",
        p_fr: "Formation continue des agents de santé, intégration de la vaccination dans le paquet de soins essentiels, amélioration du système d'information sanitaire (DHIS2), supervision intégrée.",
        p_en: "Continuous health-worker training, integration of immunization into the essential service package, health information system improvement (DHIS2), integrated supervision.", p_es: "Formación continua del personal de salud, integración de la vacunación en el paquete de atención esencial, mejora del sistema de información sanitaria (DHIS2), supervisión integrada.",
      },
      {
        h_fr: "4.3 Chaîne d'approvisionnement & chaîne du froid",
        h_en: "4.3 Supply Chain & Cold Chain", h_es: "4.3 Cadena de suministro y cadena de frío",
        p_fr: "Capacité de stockage frigorifique (PQS), gestion des températures, vérification d'étanchéité, gestion des déchets d'activités de soins, suivi des consommations et plan d'approvisionnement.",
        p_en: "Cold storage capacity (PQS), temperature monitoring, integrity checks, healthcare waste management, consumption tracking and procurement plan.", p_es: "Capacidad de almacenamiento frigorífico (PQS), gestión de las temperaturas, verificación de estanqueidad, gestión de los residuos de actividades de atención sanitaria, seguimiento de los consumos y plan de suministro.",
      },
      {
        h_fr: "4.4 Surveillance épidémiologique",
        h_en: "4.4 Epidemiological Surveillance", h_es: "4.4 Vigilancia epidemiológica",
        p_fr: "Surveillance des Maladies à Potentiel Vaccinal Évitable (MPVE) — rougeole, polio, méningite, fièvre jaune — investigation des cas suspects, réactivité aux flambées épidémiques.",
        p_en: "Surveillance of Vaccine-Preventable Diseases (VPDs) — measles, polio, meningitis, yellow fever — investigation of suspected cases, outbreak responsiveness.", p_es: "Vigilancia de las Enfermedades Prevenibles por Vacunación (EPV) — sarampión, polio, meningitis, fiebre amarilla — investigación de los casos sospechosos, capacidad de respuesta ante los brotes epidémicos.",
      },
      {
        h_fr: "4.5 Création de la demande & engagement communautaire",
        h_en: "4.5 Demand Creation & Community Engagement", h_es: "4.5 Creación de demanda y participación comunitaria",
        p_fr: "Communication interpersonnelle, dialogue communautaire, mobilisation des leaders religieux et traditionnels, gestion des rumeurs et hésitations vaccinales, ciblage des populations difficiles à atteindre.",
        p_en: "Interpersonal communication, community dialogue, mobilization of religious and traditional leaders, rumor and vaccine-hesitancy management, targeting of hard-to-reach populations.", p_es: "Comunicación interpersonal, diálogo comunitario, movilización de los líderes religiosos y tradicionales, gestión de rumores y reticencias a la vacunación, focalización de las poblaciones de difícil acceso.",
      },
      {
        h_fr: "4.6 Financement durable",
        h_en: "4.6 Sustainable Financing", h_es: "4.6 Financiación sostenible",
        p_fr: "Plan de transition GAVI, mobilisation des ressources domestiques, allocation budgétaire pour les vaccins traditionnels et les nouveaux antigènes (HPV, PCV, rotavirus).",
        p_en: "GAVI transition plan, domestic resource mobilization, budgetary allocation for traditional vaccines and new antigens (HPV, PCV, rotavirus).", p_es: "Plan de transición GAVI, movilización de recursos nacionales, asignación presupuestaria para las vacunas tradicionales y los nuevos antígenos (HPV, PCV, rotavirus).",
      },
    ];

    comps.forEach((c) => {
      out.push(H(2, s.L(lang, c.h_fr, c.h_en), { color: GAVI_COLOR }));
      out.push(P(s.L(lang, c.p_fr, c.p_en)));
    });

    return out;
  }

  // ── Monitoring & Evaluation Plan ───────────────────────────────────────
  function buildMEPlan({ lang }) {
    const s = _shared();
    const { H, P, PageBreak } = s;
    const out = [];
    out.push(PageBreak());
    out.push(H(1, s.L(lang, "5. Plan de suivi-évaluation", "5. Monitoring & Evaluation Plan", "5. Plan de seguimiento y evaluación"), { color: GAVI_COLOR }));
    out.push(P(s.L(lang,
      "Le plan de S&E articule les sources de données, les fréquences de collecte et les responsabilités. Il repose sur trois sources principales : (1) DHIS2 / système national d'information sanitaire, (2) collecte terrain MELR (PWA mobile hors-ligne), (3) enquêtes spécifiques (EDS, MICS, post-campagne).",
      "The M&E plan articulates data sources, collection frequencies, and responsibilities. It rests on three main sources: (1) DHIS2 / national health information system, (2) MELR field data collection (offline mobile PWA), (3) specific surveys (DHS, MICS, post-campaign).", "El plan de S&E articula las fuentes de datos, las frecuencias de recopilación y las responsabilidades. Se basa en tres fuentes principales: (1) DHIS2 / sistema nacional de información sanitaria, (2) recopilación de datos de terreno MELR (PWA móvil sin conexión), (3) encuestas específicas (EDS, MICS, poscampaña).")));

    out.push(H(2, s.L(lang, "Sources de données", "Data sources", "Fuentes de datos"), { color: GAVI_COLOR }));
    out.push(P("• " + s.L(lang, "DHIS2 — données administratives mensuelles agrégées par district", "DHIS2 — monthly administrative data aggregated by district", "DHIS2 — datos administrativos mensuales agregados por distrito")));
    out.push(P("• " + s.L(lang, "MELR PWA — collecte terrain en temps réel par les agents (offline-first)", "MELR PWA — real-time field collection by agents (offline-first)", "MELR PWA — recopilación de terreno en tiempo real por los agentes (offline-first)")));
    out.push(P("• " + s.L(lang, "Enquêtes ménages — EDS, MICS, MICS-Plus (couvertures officielles WUENIC)", "Household surveys — DHS, MICS, MICS-Plus (official WUENIC coverages)", "Encuestas de hogares — EDS, MICS, MICS-Plus (coberturas oficiales WUENIC)")));
    out.push(P("• " + s.L(lang, "Couvertures administratives campagnes — rougeole-rubéole, polio, fièvre jaune", "Administrative campaign coverages — measles-rubella, polio, yellow fever", "Coberturas administrativas de campañas — sarampión-rubéola, polio, fiebre amarilla")));

    out.push(H(2, s.L(lang, "Fréquences de collecte", "Collection frequencies", "Frecuencias de recopilación"), { color: GAVI_COLOR }));
    out.push(P("• " + s.L(lang, "Mensuelle : indicateurs de couverture (DTP3, MCV1, etc.)", "Monthly: coverage indicators (DTP3, MCV1, etc.)", "Mensual: indicadores de cobertura (DTP3, MCV1, etc.)")));
    out.push(P("• " + s.L(lang, "Trimestrielle : indicateurs de dropout, gestion des stocks", "Quarterly: dropout indicators, stock management", "Trimestral: indicadores de abandono, gestión de existencias")));
    out.push(P("• " + s.L(lang, "Annuelle : couvertures consolidées WUENIC, dénombrement cible", "Annual: consolidated WUENIC coverages, target population denominator", "Anual: coberturas consolidadas WUENIC, recuento de la población meta")));
    out.push(P("• " + s.L(lang, "Quinquennale : enquêtes EDS / MICS pour validation indépendante", "Quinquennial: DHS / MICS surveys for independent validation", "Quinquenal: encuestas EDS / MICS para validación independiente")));

    out.push(H(2, s.L(lang, "Qualité des données", "Data quality", "Calidad de los datos"), { color: GAVI_COLOR }));
    out.push(P(s.L(lang,
      "Une Évaluation de la Qualité des Données (DQA) est conduite annuellement sur l'ensemble du cadre de performance. Les écarts entre couverture administrative et couverture enquête sont documentés et expliqués (dénominateur, intégrité des données, validité).",
      "A Data Quality Assessment (DQA) is conducted annually across the entire performance framework. Discrepancies between administrative and survey coverage are documented and explained (denominator, data integrity, validity).", "Anualmente se realiza una Evaluación de la Calidad de los Datos (DQA) sobre la totalidad del marco de desempeño. Las discrepancias entre la cobertura administrativa y la cobertura por encuesta se documentan y explican (denominador, integridad de los datos, validez).")));

    return out;
  }

  // ── Risk register ──────────────────────────────────────────────────────
  function buildRiskRegister({ lang }) {
    const s = _shared();
    const { H, P, Cell, Row, Tbl, PageBreak } = s;
    const out = [];
    out.push(PageBreak());
    out.push(H(1, s.L(lang, "6. Registre des risques", "6. Risk Register", "6. Registro de riesgos"), { color: GAVI_COLOR }));
    out.push(P(s.L(lang,
      "Les principaux risques susceptibles d'affecter la performance du programme et les mesures de mitigation associées.",
      "Main risks likely to affect programme performance and associated mitigation measures.", "Los principales riesgos que pueden afectar al desempeño del programa y las medidas de mitigación asociadas.")));

    const hdr = { bold: true, color: "FFFFFF", fill: GAVI_COLOR };
    const headerRow = Row([
      Cell(s.L(lang, "Risque", "Risk", "Riesgo"),               { ...hdr, width: 2800 }),
      Cell(s.L(lang, "Probabilité", "Likelihood", "Probabilidad"),    { ...hdr, width: 1200, align: window.docx.AlignmentType.CENTER }),
      Cell(s.L(lang, "Impact", "Impact"),             { ...hdr, width: 1200, align: window.docx.AlignmentType.CENTER }),
      Cell(s.L(lang, "Mesure d'atténuation", "Mitigation", "Medida de mitigación"), { ...hdr, width: 4160 }),
    ]);

    const risks = [
      { fr: "Rupture de stock vaccins traceurs",       en: "Stockout of tracer vaccines", es: "Desabastecimiento de vacunas trazadoras",
        prob: s.L(lang, "Modérée", "Moderate", "Moderada"), impact: s.L(lang, "Élevé", "High", "Alto"),
        mit_fr: "Stock de sécurité 3 mois, suivi mensuel des consommations, plan d'approvisionnement glissant.",
        mit_en: "3-month safety stock, monthly consumption tracking, rolling procurement plan.", mit_es: "Existencias de seguridad de 3 meses, seguimiento mensual de los consumos, plan de suministro deslizante." },
      { fr: "Hésitation vaccinale & rumeurs",          en: "Vaccine hesitancy & rumors", es: "Reticencia vacunal y rumores",
        prob: s.L(lang, "Modérée", "Moderate", "Moderada"), impact: s.L(lang, "Modéré", "Moderate", "Moderado"),
        mit_fr: "Plan de communication communautaire, engagement des leaders religieux, hotline rumeurs.",
        mit_en: "Community communication plan, religious leader engagement, rumor hotline.", mit_es: "Plan de comunicación comunitaria, implicación de los líderes religiosos, línea directa de rumores." },
      { fr: "Insécurité / accès aux districts fragiles", en: "Insecurity / access to fragile districts", es: "Inseguridad / acceso a distritos frágiles",
        prob: s.L(lang, "Élevée", "High", "Alta"), impact: s.L(lang, "Élevé", "High", "Alto"),
        mit_fr: "Stratégies mobiles, partenariats ONG locales, coordination avec sécurité civile.",
        mit_en: "Mobile strategies, local NGO partnerships, civil security coordination.", mit_es: "Estrategias móviles, alianzas con ONG locales, coordinación con la protección civil." },
      { fr: "Coupures chaîne du froid",                en: "Cold chain breakdowns", es: "Cortes en la cadena de frío",
        prob: s.L(lang, "Faible", "Low", "Baja"), impact: s.L(lang, "Élevé", "High", "Alto"),
        mit_fr: "Maintenance préventive trimestrielle, équipements PQS solaires de secours.",
        mit_en: "Quarterly preventive maintenance, backup solar PQS equipment.", mit_es: "Mantenimiento preventivo trimestral, equipos PQS solares de respaldo." },
      { fr: "Diminution du financement domestique",    en: "Decrease in domestic financing", es: "Disminución del financiamiento doméstico",
        prob: s.L(lang, "Modérée", "Moderate", "Moderada"), impact: s.L(lang, "Élevé", "High", "Alto"),
        mit_fr: "Plaidoyer budgétaire annuel, démonstration du ROI vaccination.",
        mit_en: "Annual budget advocacy, vaccination ROI demonstration.", mit_es: "Promoción presupuestaria anual, demostración del ROI de la vacunación." },
    ];

    const rows = [headerRow].concat(risks.map((r) => Row([
      Cell(s.L(lang, r.fr, r.en),         { width: 2800, size: 18 }),
      Cell(r.prob,                         { width: 1200, size: 18, align: window.docx.AlignmentType.CENTER }),
      Cell(r.impact,                       { width: 1200, size: 18, align: window.docx.AlignmentType.CENTER }),
      Cell(s.L(lang, r.mit_fr, r.mit_en), { width: 4160, size: 18 }),
    ])));

    out.push(Tbl(rows, { columnWidths: [2800, 1200, 1200, 4160] }));

    return out;
  }

  // ── Master builder ──────────────────────────────────────────────────────
  function buildGaviDoc({ projects, indicators, scope, year, scopeLabel, orgName, lang }) {
    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(...buildCountryContext({ projects, indicators, scopeLabel, lang }));
    children.push(...buildStrategicObjectives({ lang }));
    children.push(...buildPerformanceFramework({ indicators, year, lang }));
    children.push(...buildProgrammeComponents({ lang }));
    children.push(...buildMEPlan({ lang }));
    children.push(...buildRiskRegister({ lang }));

    return new Document({
      creator: "MELR",
      title: "GAVI Performance Framework — " + (scopeLabel || "Programme") + " — " + year,
      description: "GAVI Performance Framework auto-generated by MELR",
      styles: {
        default: { document: { run: { font: "Calibri", size: 22 } } },
      },
      sections: [{
        properties: {
          page: {
            margin: { top: 1200, right: 1200, bottom: 1200, left: 1200 },
            size: { width: 11906, height: 16838 }, // A4
          },
        },
        footers: {
          default: new Footer({
            children: [new Paragraph({
              alignment: AlignmentType.CENTER,
              children: [
                new TextRun({ text: "GAVI Performance Framework · " + (scopeLabel || "Programme") + " · " + 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,
      }],
    });
  }

  // ── Public entry point ─────────────────────────────────────────────────
  async function exportGaviFramework(args) {
    args = args || {};
    if (!_ok()) {
      alert((args.lang || "fr") === "fr" ? "Module partagé indisponible." : "Shared module unavailable.");
      return;
    }
    const s = _shared();
    try {
      const doc = buildGaviDoc({
        projects: args.projects || [],
        indicators: args.indicators || [],
        scope: args.scope || { mode: "all" },
        year: args.year || new Date().getFullYear(),
        scopeLabel: args.scopeLabel || s.L(args.lang, "Programme national", "National programme", "Programa nacional"),
        orgName: args.orgName || "",
        lang: args.lang || "fr",
      });
      await s.saveDocx(doc, (args.filename || ("GAVI-Performance-Framework-" + (args.year || new Date().getFullYear()))), args.lang);
    } catch (e) {
      console.error("[GAVI export]", e);
      alert(((args.lang || "fr") === "fr" ? "Erreur GAVI : " : "GAVI error: ") + e.message);
    }
  }

  window.exportGaviFramework = exportGaviFramework;
})();
