/* global window */
// ============================================================================
// MELR · European Union (EU / INTPA) report export
// ----------------------------------------------------------------------------
// Generates an EU-formatted project monitoring report as a .docx file.
//
// The European Union (via DG INTPA, formerly DG DEVCO) requires a Logical
// Framework Matrix (logframe) for every cooperation project, plus periodic
// monitoring reports using the ROM (Results Oriented Monitoring) approach.
// The 4-column logframe is the canonical EU artifact: Intervention Logic /
// Objectively Verifiable Indicators / Sources of Verification / Assumptions.
//
// Generated structure:
//   1. Cover Page (EU blue + gold)
//   2. Project identification
//   3. Implementation status (narrative)
//   4. Logframe Matrix (4 columns × logical levels)
//   5. Indicator achievement table
//   6. Risk Matrix
//   7. Sustainability assessment
//
// Entry point: window.exportEuReport({...})
// Uses shared helpers via window.melrDonor.
// ============================================================================

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

  const EU_BLUE = "003399";   // Official EU blue
  const EU_GOLD = "FFCC00";   // EU gold (stars)

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

  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: "★ ★ ★", size: 56, color: EU_GOLD })],
      }),
      new Paragraph({
        alignment: AlignmentType.CENTER,
        spacing: { after: 200 },
        children: [new TextRun({ text: L(lang, "Union européenne", "European Union", "Unión Europea"), bold: true, size: 48, color: EU_BLUE })],
      }),
      new Paragraph({
        alignment: AlignmentType.CENTER,
        children: [new TextRun({ text: "★ ★ ★", size: 56, color: EU_GOLD })],
      }),
      new Paragraph({
        alignment: AlignmentType.CENTER,
        spacing: { before: 400, after: 600 },
        children: [new TextRun({ text: L(lang, "Rapport de suivi de projet — méthodologie ROM",
                                              "Project Monitoring Report — ROM methodology", "Informe de seguimiento del proyecto — metodología ROM"), bold: true, size: 28, color: EU_BLUE })],
      }),
      new Paragraph({
        alignment: AlignmentType.CENTER,
        spacing: { after: 200 },
        children: [new TextRun({ text: scopeLabel || L(lang, "Projet coopération", "Cooperation project", "Proyecto de cooperación"), bold: true, size: 26 })],
      }),
      new Paragraph({
        alignment: AlignmentType.CENTER,
        spacing: { after: 200 },
        children: [new TextRun({ text: orgName || L(lang, "Organisation de mise en œuvre", "Implementing organisation", "Organización de ejecución"), size: 22, 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 })],
      }),
    ];
  }

  function buildProjectId({ projects, scopeLabel, lang }) {
    const s = _shared();
    const { H, P, Cell, Row, Tbl, Spacer } = s;
    const out = [];
    out.push(H(1, s.L(lang, "1. Identification du projet", "1. Project Identification", "1. Identificación del proyecto"), { color: EU_BLUE }));
    out.push(P(s.L(lang,
      "Cette section reprend les éléments d'identification du projet figurant dans la convention de financement (CDF) signée avec la Délégation de l'Union Européenne.",
      "This section reproduces the project identification elements from the financing convention (FA) signed with the European Union Delegation.", "Esta sección recoge los elementos de identificación del proyecto que figuran en el convenio de financiación (CDF) firmado con la Delegación de la Unión Europea.")));

    const FILL = "F3F4F6";
    const items = [
      [s.L(lang, "Intitulé du projet", "Project title", "Título del proyecto"),                  scopeLabel || "—"],
      [s.L(lang, "Référence CDF / IATI", "FA reference / IATI", "Referencia CDF / IATI"),         s.L(lang, "À renseigner", "To be completed", "Por cumplimentar")],
      [s.L(lang, "Pays / région", "Country / region", "País / región"),                    ((projects || [])[0]?.countries || [(projects || [])[0]?.country]).filter(Boolean).join(", ") || "—"],
      [s.L(lang, "Secteur DAC", "DAC sector", "Sector CAD"),                            ((projects || [])[0]?.sector || (projects || [])[0]?.sectorCode || "—")],
      [s.L(lang, "Durée prévue", "Planned duration", "Duración prevista"),                     s.L(lang, "À renseigner (cf. CDF)", "To be completed (see FA)", "Por cumplimentar (véase CDF)")],
      [s.L(lang, "Coût total estimé", "Total estimated cost", "Costo total estimado"),            s.L(lang, "À renseigner (cf. CDF)", "To be completed (see FA)", "Por cumplimentar (véase CDF)")],
      [s.L(lang, "Contribution UE", "EU contribution", "Contribución UE"),                   s.L(lang, "À renseigner (cf. CDF)", "To be completed (see FA)", "Por cumplimentar (véase CDF)")],
      [s.L(lang, "Co-financements", "Co-financing", "Cofinanciaciones"),                      s.L(lang, "À renseigner", "To be completed", "Por cumplimentar")],
    ];
    const rows = items.map(([k, v]) => Row([
      Cell(k, { width: 3000, bold: true, fill: FILL, color: EU_BLUE, size: 18 }),
      Cell(v, { width: 6360, size: 20 }),
    ]));
    out.push(Tbl(rows, { columnWidths: [3000, 6360] }));
    out.push(Spacer());

    return out;
  }

  function buildImplementation({ lang }) {
    const s = _shared();
    const { H, P, PageBreak } = s;
    const out = [];
    out.push(PageBreak());
    out.push(H(1, s.L(lang, "2. État d'avancement de la mise en œuvre", "2. Implementation Status", "2. Estado de avance de la ejecución"), { color: EU_BLUE }));
    out.push(P(s.L(lang,
      "Narration synthétique sur l'avancement par composante, les réalisations clés, les retards éventuels et les ajustements opérés. La méthodologie ROM impose une appréciation sur cinq critères CAD-OCDE : pertinence, efficacité, efficience, impact, durabilité.",
      "Synthetic narration on progress per component, key achievements, delays if any, and adjustments made. The ROM methodology requires an assessment against five OECD-DAC criteria: relevance, effectiveness, efficiency, impact, sustainability.", "Narración sintética sobre el avance por componente, los logros clave, los posibles retrasos y los ajustes realizados. La metodología ROM exige una valoración según cinco criterios CAD-OCDE: pertinencia, eficacia, eficiencia, impacto, sostenibilidad.")));
    out.push(P(s.L(lang, "(À compléter manuellement à partir des données MELR du cycle de reporting.)",
                        "(To be completed manually from MELR data for the reporting cycle.)", "(A completar manualmente a partir de los datos MELR del ciclo de presentación de informes.)"), { run: { italics: true, color: s.COLORS.MUTED } }));

    const criteria = [
      { fr: "Pertinence",      en: "Relevance",      es: "Pertinencia",   def_fr: "Le projet répond-il aux besoins des bénéficiaires et aux priorités UE ?", def_en: "Does the project respond to beneficiary needs and EU priorities?", def_es: "¿Responde el proyecto a las necesidades de los beneficiarios y a las prioridades de la UE?" },
      { fr: "Efficacité",      en: "Effectiveness",  es: "Eficacia",      def_fr: "Les objectifs spécifiques sont-ils en voie d'être atteints ?",            def_en: "Are the specific objectives on track to be achieved?", def_es: "¿Están los objetivos específicos en vías de alcanzarse?" },
      { fr: "Efficience",      en: "Efficiency",     es: "Eficiencia",    def_fr: "Les ressources sont-elles utilisées de manière économique ?",             def_en: "Are resources being used economically?", def_es: "¿Se utilizan los recursos de manera económica?" },
      { fr: "Impact",          en: "Impact",         es: "Impacto",       def_fr: "Le projet produit-il des effets positifs durables ?",                       def_en: "Is the project producing lasting positive effects?", def_es: "¿Produce el proyecto efectos positivos duraderos?" },
      { fr: "Durabilité",      en: "Sustainability", es: "Sostenibilidad", def_fr: "Les acquis seront-ils maintenus après la fin du financement ?",            def_en: "Will achievements be maintained after funding ends?", def_es: "¿Se mantendrán los logros una vez finalizada la financiación?" },
    ];
    criteria.forEach((c) => {
      out.push(P("• " + s.L(lang, c.fr, c.en) + " : " + s.L(lang, c.def_fr, c.def_en), { run: { size: 22 } }));
    });

    return out;
  }

  function buildLogframeMatrix({ indicators, lang }) {
    const s = _shared();
    const { H, P, Cell, Row, Tbl, PageBreak } = s;
    const out = [];
    out.push(PageBreak());
    out.push(H(1, s.L(lang, "3. Matrice du cadre logique", "3. Logical Framework Matrix", "3. Matriz del marco lógico"), { color: EU_BLUE }));
    out.push(P(s.L(lang,
      "Le cadre logique selon le standard UE articule la chaîne d'intervention en quatre niveaux : Objectif global → Objectif spécifique → Résultats → Activités. Chaque niveau est décliné en quatre colonnes : Logique d'intervention, Indicateurs Objectivement Vérifiables (IOV), Sources de vérification, Hypothèses.",
      "The EU-standard logframe articulates the intervention chain in four levels: Overall Objective → Specific Objective → Results → Activities. Each level is broken down into four columns: Intervention Logic, Objectively Verifiable Indicators (OVI), Sources of Verification, Assumptions.", "El marco lógico según el estándar de la UE articula la cadena de intervención en cuatro niveles: Objetivo global → Objetivo específico → Resultados → Actividades. Cada nivel se desglosa en cuatro columnas: Lógica de intervención, Indicadores Objetivamente Verificables (IOV), Fuentes de verificación, Supuestos.")));

    const hdr = { bold: true, color: "FFFFFF", fill: EU_BLUE };
    const matrixHeader = Row([
      Cell("",                                                  { ...hdr, width: 1400 }),
      Cell(s.L(lang, "Logique d'intervention", "Intervention logic", "Lógica de intervención"), { ...hdr, width: 2800 }),
      Cell(s.L(lang, "Indicateurs (IOV)", "Indicators (OVI)", "Indicadores (IOV)"),  { ...hdr, width: 2400 }),
      Cell(s.L(lang, "Sources de vérification", "Sources of verification", "Fuentes de verificación"), { ...hdr, width: 1400 }),
      Cell(s.L(lang, "Hypothèses", "Assumptions", "Supuestos"),              { ...hdr, width: 1360 }),
    ]);

    const bag = s.groupByLevel(indicators);
    function flatList(arr) {
      if (!arr || arr.length === 0) return s.L(lang, "À définir", "To be defined", "Por definir");
      return arr.slice(0, 4).map((i) => "• " + (i.id || i.code || "—") + " — " + (lang === "fr" ? (i.name_fr || i.name) : (i.name_en || i.name))).join("\n");
    }

    const matrixRows = [matrixHeader,
      Row([
        Cell(s.L(lang, "Objectif global", "Overall Objective", "Objetivo global"), { width: 1400, bold: true, fill: "E0E7FF", color: EU_BLUE, size: 18 }),
        Cell(s.L(lang, "Contribuer aux Objectifs de Développement Durable et aux politiques de coopération UE.",
                       "Contribute to the Sustainable Development Goals and EU cooperation policies.", "Contribuir a los Objetivos de Desarrollo Sostenible y a las políticas de cooperación de la UE."), { width: 2800, size: 18 }),
        Cell(flatList(bag.Impact), { width: 2400, size: 18 }),
        Cell(s.L(lang, "Statistiques nationales, rapports ODD",
                       "National statistics, SDG reports", "Estadísticas nacionales, informes ODS"), { width: 1400, size: 18 }),
        Cell(s.L(lang, "Stabilité macroéconomique et politique",
                       "Macroeconomic and political stability", "Estabilidad macroeconómica y política"), { width: 1360, size: 18 }),
      ]),
      Row([
        Cell(s.L(lang, "Objectif spécifique", "Specific Objective", "Objetivo específico"), { width: 1400, bold: true, fill: "E0E7FF", color: EU_BLUE, size: 18 }),
        Cell(s.L(lang, "Atteindre les résultats intermédiaires sectoriels.",
                       "Achieve sectoral intermediate results.", "Alcanzar los resultados intermedios sectoriales."), { width: 2800, size: 18 }),
        Cell(flatList(bag.Outcome), { width: 2400, size: 18 }),
        Cell(s.L(lang, "Système S&E MELR, supervisions, ROM",
                       "MELR M&E system, supervisions, ROM", "Sistema de S&E MELR, supervisiones, ROM"), { width: 1400, size: 18 }),
        Cell(s.L(lang, "Adhésion des bénéficiaires, partenariats fonctionnels",
                       "Beneficiary buy-in, functional partnerships", "Adhesión de los beneficiarios, alianzas funcionales"), { width: 1360, size: 18 }),
      ]),
      Row([
        Cell(s.L(lang, "Résultats", "Results", "Resultados"), { width: 1400, bold: true, fill: "E0E7FF", color: EU_BLUE, size: 18 }),
        Cell(s.L(lang, "Livrer les outputs prévus par les composantes du projet.",
                       "Deliver outputs planned by project components.", "Entregar los productos previstos por los componentes del proyecto."), { width: 2800, size: 18 }),
        Cell(flatList(bag.Output), { width: 2400, size: 18 }),
        Cell(s.L(lang, "Rapports d'activités, livrables, registres",
                       "Activity reports, deliverables, registers", "Informes de actividades, entregables, registros"), { width: 1400, size: 18 }),
        Cell(s.L(lang, "Disponibilité des ressources humaines et matérielles",
                       "Availability of human and material resources", "Disponibilidad de recursos humanos y materiales"), { width: 1360, size: 18 }),
      ]),
      Row([
        Cell(s.L(lang, "Activités", "Activities", "Actividades"), { width: 1400, bold: true, fill: "E0E7FF", color: EU_BLUE, size: 18 }),
        Cell(s.L(lang, "Exécuter les actions planifiées (cf. plan opérationnel).",
                       "Execute planned actions (see operational plan).", "Ejecutar las acciones planificadas (véase el plan operativo)."), { width: 2800, size: 18 }),
        Cell(s.L(lang, "Indicateurs d'effort (jours, missions, formations)",
                       "Effort indicators (days, missions, trainings)", "Indicadores de esfuerzo (días, misiones, formaciones)"), { width: 2400, size: 18 }),
        Cell(s.L(lang, "Journaux MELR, GPS, photos",
                       "MELR journals, GPS, photos", "Diarios MELR, GPS, fotos"), { width: 1400, size: 18 }),
        Cell(s.L(lang, "Pré-conditions remplies à T0",
                       "Pre-conditions met at T0", "Condiciones previas cumplidas en T0"), { width: 1360, size: 18 }),
      ]),
    ];

    out.push(Tbl(matrixRows, { columnWidths: [1400, 2800, 2400, 1400, 1360] }));

    return out;
  }

  function buildAchievement({ 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, "4. Atteinte des indicateurs", "4. Indicator Achievement", "4. Consecución de los indicadores"), { color: EU_BLUE }));
    out.push(P(s.L(lang,
      "Suivi quantifié des Indicateurs Objectivement Vérifiables (IOV) sur trois exercices fiscaux. Notation ROM : satisfaisant ≥ 90 %, partiellement satisfaisant 70-89 %, insuffisant < 70 %.",
      "Quantified tracking of Objectively Verifiable Indicators (OVI) over three fiscal years. ROM rating: satisfactory ≥ 90 %, partially satisfactory 70-89 %, unsatisfactory < 70 %.", "Seguimiento cuantificado de los Indicadores Objetivamente Verificables (IOV) a lo largo de tres ejercicios fiscales. Calificación ROM: satisfactorio ≥ 90 %, parcialmente satisfactorio 70-89 %, insuficiente < 70 %.")));

    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: EU_BLUE };
    const headerCells = [
      Cell(s.L(lang, "Code", "Code"),                  { ...hdr, width: 800 }),
      Cell(s.L(lang, "Indicateur (IOV)", "Indicator (OVI)", "Indicador (IOV)"), { ...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;
  }

  function buildRiskMatrix({ lang }) {
    const s = _shared();
    const { H, P, Cell, Row, Tbl, PageBreak } = s;
    const out = [];
    out.push(PageBreak());
    out.push(H(1, s.L(lang, "5. Matrice des risques", "5. Risk Matrix", "5. Matriz de riesgos"), { color: EU_BLUE }));
    out.push(P(s.L(lang,
      "Conformément à la grille INTPA, les risques sont évalués selon trois dimensions : probabilité, impact, niveau résiduel après mesures d'atténuation.",
      "Per the INTPA framework, risks are assessed across three dimensions: likelihood, impact, residual level after mitigation measures.", "Conforme a la matriz INTPA, los riesgos se evalúan según tres dimensiones: probabilidad, impacto, nivel residual tras las medidas de mitigación.")));

    const hdr = { bold: true, color: "FFFFFF", fill: EU_BLUE };
    const rows = [Row([
      Cell(s.L(lang, "Risque", "Risk", "Riesgo"),                { ...hdr, width: 3000 }),
      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: 2800 }),
      Cell(s.L(lang, "Résiduel", "Residual", "Residual"),          { ...hdr, width: 1160, align: window.docx.AlignmentType.CENTER }),
    ])];
    const risks = [
      { r_fr: "Volatilité des taux de change",        r_en: "Exchange rate volatility", r_es: "Volatilidad de los tipos de cambio",
        p: s.L(lang, "Modérée", "Moderate", "Moderada"), i: s.L(lang, "Élevé", "High", "Alto"),
        m_fr: "Suivi mensuel, clauses d'ajustement, marges de couverture.",
        m_en: "Monthly tracking, adjustment clauses, hedging margins.", m_es: "Seguimiento mensual, cláusulas de ajuste, márgenes de cobertura.",
        res: s.L(lang, "Modéré", "Moderate", "Moderado") },
      { r_fr: "Retards de procédures de passation",   r_en: "Procurement procedure delays", r_es: "Retrasos en los procedimientos de contratación",
        p: s.L(lang, "Élevée", "High", "Alta"), i: s.L(lang, "Modéré", "Moderate", "Moderado"),
        m_fr: "Plan glissant, anticipation, expertise PRAG.",
        m_en: "Rolling plan, anticipation, PRAG expertise.", m_es: "Plan deslizante, anticipación, experiencia PRAG.",
        res: s.L(lang, "Modéré", "Moderate", "Moderado") },
      { r_fr: "Faible appropriation par les partenaires", r_en: "Low partner ownership", r_es: "Baja apropiación por parte de los socios",
        p: s.L(lang, "Modérée", "Moderate", "Moderada"), i: s.L(lang, "Élevé", "High", "Alto"),
        m_fr: "Comités de pilotage trimestriels, gouvernance partagée, formations.",
        m_en: "Quarterly steering committees, shared governance, trainings.", m_es: "Comités de dirección trimestrales, gobernanza compartida, formaciones.",
        res: s.L(lang, "Faible", "Low", "Baja") },
      { r_fr: "Changements de cadre politique national", r_en: "Changes in national policy framework", r_es: "Cambios en el marco político nacional",
        p: s.L(lang, "Faible", "Low", "Baja"), i: s.L(lang, "Élevé", "High", "Alto"),
        m_fr: "Veille politique, dialogue institutionnel, scénarios de repli.",
        m_en: "Policy monitoring, institutional dialogue, fallback scenarios.", m_es: "Vigilancia política, diálogo institucional, escenarios de repliegue.",
        res: s.L(lang, "Modéré", "Moderate", "Moderado") },
      { r_fr: "Risques sécuritaires sur zones d'intervention", r_en: "Security risks in intervention areas", r_es: "Riesgos de seguridad en las zonas de intervención",
        p: s.L(lang, "Variable", "Variable"), i: s.L(lang, "Élevé", "High", "Alto"),
        m_fr: "Plans sécuritaires, partenariats locaux, modalités de mise en œuvre à distance.",
        m_en: "Security plans, local partnerships, remote implementation modalities.", m_es: "Planes de seguridad, alianzas locales, modalidades de ejecución a distancia.",
        res: s.L(lang, "Modéré", "Moderate", "Moderado") },
    ];
    risks.forEach((r) => rows.push(Row([
      Cell(s.L(lang, r.r_fr, r.r_en), { width: 3000, size: 18 }),
      Cell(r.p,                        { width: 1200, size: 18, align: window.docx.AlignmentType.CENTER }),
      Cell(r.i,                        { width: 1200, size: 18, align: window.docx.AlignmentType.CENTER }),
      Cell(s.L(lang, r.m_fr, r.m_en), { width: 2800, size: 18 }),
      Cell(r.res,                      { width: 1160, size: 18, align: window.docx.AlignmentType.CENTER }),
    ])));
    out.push(Tbl(rows, { columnWidths: [3000, 1200, 1200, 2800, 1160] }));

    return out;
  }

  function buildSustainability({ lang }) {
    const s = _shared();
    const { H, P, PageBreak } = s;
    const out = [];
    out.push(PageBreak());
    out.push(H(1, s.L(lang, "6. Évaluation de la durabilité", "6. Sustainability Assessment", "6. Evaluación de la sostenibilidad"), { color: EU_BLUE }));
    out.push(P(s.L(lang,
      "La durabilité est évaluée selon les dimensions standard INTPA : institutionnelle, financière, sociale, environnementale, technique. Cette section présente l'analyse synthétique pour chaque dimension.",
      "Sustainability is assessed against the standard INTPA dimensions: institutional, financial, social, environmental, technical. This section presents the synthetic analysis for each dimension.", "La sostenibilidad se evalúa según las dimensiones estándar de INTPA: institucional, financiera, social, medioambiental, técnica. Esta sección presenta el análisis sintético de cada dimensión.")));

    const dims = [
      { fr: "Institutionnelle", en: "Institutional", es: "Institucional",
        d_fr: "Capacités institutionnelles transférées, ancrage dans les ministères ou collectivités.",
        d_en: "Institutional capacities transferred, anchored in ministries or local authorities.", d_es: "Capacidades institucionales transferidas, anclaje en los ministerios o entidades locales." },
      { fr: "Financière", en: "Financial", es: "Financiera",
        d_fr: "Plan de mobilisation de ressources post-projet, engagements budgétaires nationaux.",
        d_en: "Post-project resource mobilization plan, national budget commitments.", d_es: "Plan de movilización de recursos posproyecto, compromisos presupuestarios nacionales." },
      { fr: "Sociale", en: "Social", es: "Social",
        d_fr: "Appropriation par les communautés bénéficiaires, équité de genre, inclusion.",
        d_en: "Ownership by beneficiary communities, gender equity, inclusion.", d_es: "Apropiación por parte de las comunidades beneficiarias, equidad de género, inclusión." },
      { fr: "Environnementale", en: "Environmental", es: "Ambiental",
        d_fr: "Conformité aux normes environnementales, prise en compte du changement climatique.",
        d_en: "Compliance with environmental standards, climate change considerations.", d_es: "Conformidad con las normas medioambientales, consideración del cambio climático." },
      { fr: "Technique", en: "Technical", es: "Técnica",
        d_fr: "Adaptation des technologies au contexte, maintenance assurée localement.",
        d_en: "Technology adaptation to context, locally-ensured maintenance.", d_es: "Adaptación de las tecnologías al contexto, mantenimiento garantizado a nivel local." },
    ];
    dims.forEach((d) => {
      out.push(P("• " + s.L(lang, d.fr, d.en) + " — " + s.L(lang, d.d_fr, d.d_en), { run: { size: 22 } }));
    });

    return out;
  }

  function buildDoc({ 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(...buildProjectId({ projects, scopeLabel, lang }));
    children.push(...buildImplementation({ lang }));
    children.push(...buildLogframeMatrix({ indicators, lang }));
    children.push(...buildAchievement({ indicators, year, lang }));
    children.push(...buildRiskMatrix({ lang }));
    children.push(...buildSustainability({ lang }));
    return new Document({
      creator: "MELR",
      title: "EU Report — " + (scopeLabel || "Projet") + " — " + year,
      description: "EU project monitoring report 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 } } },
        footers: {
          default: new Footer({
            children: [new Paragraph({
              alignment: AlignmentType.CENTER,
              children: [
                new TextRun({ text: "EU INTPA · " + (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 exportEuReport(args) {
    args = args || {};
    if (!_ok()) { alert((args.lang || "fr") === "fr" ? "Module partagé indisponible." : "Shared module unavailable."); return; }
    const s = _shared();
    try {
      const doc = buildDoc({
        projects: args.projects || [],
        indicators: args.indicators || [],
        scope: args.scope || { mode: "all" },
        year: args.year || new Date().getFullYear(),
        scopeLabel: args.scopeLabel || s.L(args.lang, "Projet", "Project", "Proyecto"),
        orgName: args.orgName || "",
        lang: args.lang || "fr",
      });
      await s.saveDocx(doc, (args.filename || ("EU-Rapport-" + (args.year || new Date().getFullYear()))), args.lang);
    } catch (e) {
      console.error("[EU export]", e);
      alert(((args.lang || "fr") === "fr" ? "Erreur UE : " : "EU error: ") + e.message);
    }
  }
  window.exportEuReport = exportEuReport;
})();
