/* global window */
// ============================================================================
// MELR · AFD (Agence Française de Développement) report export
// ----------------------------------------------------------------------------
// Generates an AFD-formatted project monitoring report as a .docx file.
//
// AFD is the French development finance agency and the largest bilateral
// donor in francophone Africa. Their reporting style follows the French
// "cadre logique" tradition: Objectif Global → Objectifs Spécifiques →
// Résultats → Activités. Reports referenced here align with the AFD
// "Document de projet" and "Rapport de mission" templates.
//
// Generated structure:
//   1. Cover Page (AFD red branding)
//   2. Présentation du projet (project summary, OG, OS, partenaires)
//   3. Cadre logique (4-column logframe matrix)
//   4. Indicateurs de performance (IPTT-style)
//   5. Avancement par composante (narrative)
//   6. Cadre budgétaire (synthèse)
//   7. Risques et mesures d'atténuation
//   8. Plan de mission / supervision
//
// Entry point: window.exportAfdReport({...})
// Uses shared helpers via window.melrDonor.
// ============================================================================

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

  const AFD_COLOR = "E2001A";           // AFD red (used in logo + headers)
  const AFD_GREY  = "3D3D3D";           // Dark grey for body accents

  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: "AFD", bold: true, size: 64, color: AFD_COLOR })],
      }),
      new Paragraph({
        alignment: AlignmentType.CENTER,
        spacing: { after: 200 },
        children: [new TextRun({ text: "Agence Française de Développement", italics: true, size: 22, color: AFD_GREY })],
      }),
      new Paragraph({
        alignment: AlignmentType.CENTER,
        spacing: { after: 600 },
        children: [new TextRun({ text: L(lang, "Rapport de suivi de projet", "Project Monitoring Report", "Informe de seguimiento del proyecto"), bold: true, size: 32, color: AFD_GREY })],
      }),
      new Paragraph({
        alignment: AlignmentType.CENTER,
        spacing: { after: 200 },
        children: [new TextRun({ text: scopeLabel || L(lang, "Projet bénéficiaire", "Beneficiary project", "Proyecto beneficiario"), bold: true, size: 28 })],
      }),
      new Paragraph({
        alignment: AlignmentType.CENTER,
        spacing: { after: 200 },
        children: [new TextRun({ text: orgName || L(lang, "Maître d'ouvrage", "Project owner", "Entidad contratante"), size: 24, color: _shared().COLORS.MUTED })],
      }),
      new Paragraph({
        alignment: AlignmentType.CENTER,
        spacing: { before: 800, after: 200 },
        children: [new TextRun({ text: L(lang, "Exercice fiscal", "Fiscal year", "Ejercicio fiscal") + " : " + 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 buildProjectSummary({ projects, scopeLabel, lang }) {
    const s = _shared();
    const { H, P, Cell, Row, Tbl, Spacer } = s;
    const out = [];
    out.push(H(1, s.L(lang, "1. Présentation du projet", "1. Project Presentation", "1. Presentación del proyecto"), { color: AFD_COLOR }));
    out.push(P(s.L(lang,
      "Cette section résume le projet financé par l'AFD : objectif global, objectifs spécifiques, partenaires, zone d'intervention et calendrier de mise en œuvre.",
      "This section summarizes the AFD-financed project: overall objective, specific objectives, partners, geographic scope, and implementation timeline.", "Esta sección resume el proyecto financiado por la AFD: objetivo global, objetivos específicos, socios, zona de intervención y calendario de ejecución.")));

    const hdr = { bold: true, color: "FFFFFF", fill: AFD_COLOR };
    const projHdr = Row([
      Cell(s.L(lang, "Code", "Code"),       { ...hdr, width: 1200 }),
      Cell(s.L(lang, "Intitulé", "Title", "Título"),  { ...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;
  }

  function buildLogframe({ 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, "2. Cadre logique", "2. Logical Framework", "2. Marco lógico"), { color: AFD_COLOR }));
    out.push(P(s.L(lang,
      "La matrice du cadre logique articule la chaîne d'intervention selon la nomenclature AFD : Objectif Global (OG), Objectifs Spécifiques (OS), Résultats attendus et Activités. Chaque niveau est doté d'indicateurs vérifiables et de sources de vérification.",
      "The logical framework matrix articulates the intervention chain following the AFD nomenclature: Overall Objective (OO), Specific Objectives (SO), Expected Results, and Activities. Each level has verifiable indicators and sources of verification.", "La matriz del marco lógico articula la cadena de intervención según la nomenclatura de la AFD: Objetivo Global (OG), Objetivos Específicos (OE), Resultados esperados y Actividades. Cada nivel cuenta con indicadores verificables y fuentes de verificación.")));

    const hdr = { bold: true, color: "FFFFFF", fill: AFD_COLOR };
    const matrixHeader = Row([
      Cell(s.L(lang, "Niveau", "Level", "Nivel"),                            { ...hdr, width: 1600 }),
      Cell(s.L(lang, "Énoncé", "Statement", "Enunciado"),                        { ...hdr, width: 3200 }),
      Cell(s.L(lang, "Indicateurs vérifiables", "Verifiable indicators", "Indicadores verificables"), { ...hdr, width: 2600 }),
      Cell(s.L(lang, "Sources de vérification", "Sources of verification", "Fuentes de verificación"), { ...hdr, width: 1960 }),
    ]);

    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 (OG)", "Overall Objective", "Objetivo global (OG)"),         { width: 1600, bold: true, fill: "FEE2E2", color: AFD_COLOR, size: 18 }),
        Cell(s.L(lang, "Contribuer durablement aux ODD et aux priorités nationales de développement.",
                       "Sustainably contribute to the SDGs and national development priorities.", "Contribuir de manera sostenible a los ODS y a las prioridades nacionales de desarrollo."), { width: 3200, size: 18 }),
        Cell(flatList(bag.Impact), { width: 2600, size: 18 }),
        Cell(s.L(lang, "Statistiques nationales, rapports ODD",
                       "National statistics, SDG reports", "Estadísticas nacionales, informes ODS"), { width: 1960, size: 18 }),
      ]),
      Row([
        Cell(s.L(lang, "Objectifs spécifiques (OS)", "Specific Objectives", "Objetivos específicos (OE)"), { width: 1600, bold: true, fill: "FEE2E2", color: AFD_COLOR, size: 18 }),
        Cell(s.L(lang, "Atteindre les résultats sectoriels intermédiaires (Outcomes) ciblés par le projet.",
                       "Achieve the targeted sectoral intermediate results (Outcomes) of the project.", "Alcanzar los resultados sectoriales intermedios (Outcomes) previstos por el proyecto."), { width: 3200, size: 18 }),
        Cell(flatList(bag.Outcome), { width: 2600, size: 18 }),
        Cell(s.L(lang, "Système de S&E MELR, supervisions, audits DVT",
                       "MELR M&E system, supervisions, DVT audits", "Sistema de S&E MELR, supervisiones, auditorías DVT"), { width: 1960, size: 18 }),
      ]),
      Row([
        Cell(s.L(lang, "Résultats attendus", "Expected Results", "Resultados esperados"),             { width: 1600, bold: true, fill: "FEE2E2", color: AFD_COLOR, size: 18 }),
        Cell(s.L(lang, "Produire les outputs prévus par les composantes du projet.",
                       "Produce the outputs planned by the project components.", "Producir los productos (outputs) previstos por los componentes del proyecto."), { width: 3200, size: 18 }),
        Cell(flatList(bag.Output), { width: 2600, size: 18 }),
        Cell(s.L(lang, "Rapports d'activités, registres terrain, livrables",
                       "Activity reports, field registers, deliverables", "Informes de actividades, registros de campo, entregables"), { width: 1960, size: 18 }),
      ]),
      Row([
        Cell(s.L(lang, "Activités", "Activities", "Actividades"),                            { width: 1600, bold: true, fill: "FEE2E2", color: AFD_COLOR, size: 18 }),
        Cell(s.L(lang, "Mettre en œuvre les actions planifiées (cf. plan d'opérations).",
                       "Implement the planned actions (see operations plan).", "Ejecutar las acciones planificadas (véase el plan de operaciones)."), { width: 3200, size: 18 }),
        Cell(s.L(lang, "Indicateurs d'effort (jours-homme, missions, formations)",
                       "Effort indicators (person-days, missions, trainings)", "Indicadores de esfuerzo (días-hombre, misiones, capacitaciones)"), { width: 2600, size: 18 }),
        Cell(s.L(lang, "Journaux d'activités MELR, GPS, photos signées",
                       "MELR activity logs, GPS, signed photos", "Registros de actividades MELR, GPS, fotografías firmadas"), { width: 1960, size: 18 }),
      ]),
    ];

    out.push(Tbl(matrixRows, { columnWidths: [1600, 3200, 2600, 1960] }));

    return out;
  }

  function buildPerformance({ 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. Indicateurs de performance", "3. Performance Indicators", "3. Indicadores de desempeño"), { color: AFD_COLOR }));
    out.push(P(s.L(lang,
      "Tableau d'avancement consolidé sur trois exercices fiscaux. L'AFD considère qu'un indicateur est satisfaisant à partir de 80 % d'atteinte de la cible annuelle.",
      "Performance tracking table consolidated over three fiscal years. AFD considers an indicator satisfactory from 80 % achievement of the annual target.", "Tabla de avance consolidada sobre tres ejercicios fiscales. La AFD considera que un indicador es satisfactorio a partir del 80 % de cumplimiento de la meta anual.")));

    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: AFD_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;
  }

  function buildProgress({ lang }) {
    const s = _shared();
    const { H, P, PageBreak } = s;
    const out = [];
    out.push(PageBreak());
    out.push(H(1, s.L(lang, "4. Avancement par composante", "4. Progress by Component", "4. Avance por componente"), { color: AFD_COLOR }));
    out.push(P(s.L(lang,
      "Cette section présente un commentaire qualitatif sur l'avancement de chaque composante du projet, mettant en évidence les réalisations marquantes, les difficultés rencontrées et les ajustements opérés.",
      "This section provides a qualitative commentary on progress for each project component, highlighting key achievements, difficulties encountered, and adjustments made.", "Esta sección presenta un comentario cualitativo sobre el avance de cada componente del proyecto, destacando los logros relevantes, las dificultades encontradas y los ajustes realizados.")));
    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 } }));
    return out;
  }

  function buildBudget({ 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. Cadre budgétaire (synthèse)", "5. Budget Framework (Summary)", "5. Marco presupuestario (síntesis)"), { color: AFD_COLOR }));
    out.push(P(s.L(lang,
      "Synthèse de l'exécution budgétaire à la date du rapport. Les détails par ligne sont à consulter dans le module Budget du projet.",
      "Summary of budget execution at the report date. Detailed line items are available in the project Budget module.", "Síntesis de la ejecución presupuestaria a la fecha del informe. Los detalles por línea pueden consultarse en el módulo Presupuesto del proyecto.")));

    const hdr = { bold: true, color: "FFFFFF", fill: AFD_COLOR };
    const rows = [Row([
      Cell(s.L(lang, "Composante", "Component", "Componente"),    { ...hdr, width: 3000 }),
      Cell(s.L(lang, "Budgété", "Budgeted", "Presupuestado"),        { ...hdr, width: 2000, align: window.docx.AlignmentType.CENTER }),
      Cell(s.L(lang, "Engagé", "Committed", "Comprometido"),        { ...hdr, width: 2000, align: window.docx.AlignmentType.CENTER }),
      Cell(s.L(lang, "Décaissé", "Disbursed", "Desembolsado"),      { ...hdr, width: 2360, align: window.docx.AlignmentType.CENTER }),
    ])];
    const components = [
      s.L(lang, "Composante 1 — Renforcement institutionnel", "Component 1 — Institutional strengthening", "Componente 1 — Fortalecimiento institucional"),
      s.L(lang, "Composante 2 — Investissements infrastructure", "Component 2 — Infrastructure investments", "Componente 2 — Inversiones en infraestructura"),
      s.L(lang, "Composante 3 — Formation et accompagnement", "Component 3 — Training and accompaniment", "Componente 3 — Capacitación y acompañamiento"),
      s.L(lang, "Composante 4 — Suivi-évaluation et capitalisation", "Component 4 — M&E and knowledge management", "Componente 4 — Seguimiento y evaluación y capitalización"),
      s.L(lang, "Imprévus & coûts de gestion", "Contingencies & management costs", "Imprevistos y costos de gestión"),
      s.L(lang, "TOTAL", "TOTAL"),
    ];
    components.forEach((c, i) => {
      const bold = i === components.length - 1;
      rows.push(Row([
        Cell(c,                                  { width: 3000, size: 18, bold }),
        Cell(s.L(lang, "À compléter", "TBD", "Por completar"),    { width: 2000, size: 18, align: window.docx.AlignmentType.CENTER, bold }),
        Cell(s.L(lang, "À compléter", "TBD", "Por completar"),    { width: 2000, size: 18, align: window.docx.AlignmentType.CENTER, bold }),
        Cell(s.L(lang, "À compléter", "TBD", "Por completar"),    { width: 2360, size: 18, align: window.docx.AlignmentType.CENTER, bold }),
      ]));
    });
    out.push(Tbl(rows, { columnWidths: [3000, 2000, 2000, 2360] }));

    return out;
  }

  function buildRisks({ 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. Risques et mesures d'atténuation", "6. Risks and Mitigation Measures", "6. Riesgos y medidas de mitigación"), { color: AFD_COLOR }));
    out.push(P(s.L(lang,
      "Suivi des principaux risques opérationnels, fiduciaires et environnementaux conformément à la grille AFD.",
      "Tracking of major operational, fiduciary, and environmental risks per the AFD framework.", "Seguimiento de los principales riesgos operativos, fiduciarios y ambientales conforme a la matriz de la AFD.")));

    const hdr = { bold: true, color: "FFFFFF", fill: AFD_COLOR };
    const rows = [Row([
      Cell(s.L(lang, "Catégorie", "Category", "Categoría"),         { ...hdr, width: 1800 }),
      Cell(s.L(lang, "Risque", "Risk", "Riesgo"),                { ...hdr, width: 2800 }),
      Cell(s.L(lang, "Probabilité × Impact", "Likelihood × Impact", "Probabilidad × Impacto"), { ...hdr, width: 1800, align: window.docx.AlignmentType.CENTER }),
      Cell(s.L(lang, "Mesure d'atténuation", "Mitigation", "Medida de mitigación"), { ...hdr, width: 2960 }),
    ])];
    const risks = [
      { cat_fr: "Opérationnel", cat_en: "Operational", cat_es: "Operativo",
        r_fr: "Retards de mise en œuvre liés aux délais de passation de marchés",
        r_en: "Implementation delays related to procurement timelines", r_es: "Retrasos en la ejecución vinculados a los plazos de contratación",
        pi: s.L(lang, "Élevée × Modéré", "High × Moderate", "Alta × Moderado"),
        m_fr: "Plan de passation glissant, anticipation des appels d'offres, accompagnement juridique.",
        m_en: "Rolling procurement plan, anticipated bidding, legal support.", m_es: "Plan de contratación deslizante, anticipación de las licitaciones, acompañamiento jurídico." },
      { cat_fr: "Fiduciaire", cat_en: "Fiduciary", cat_es: "Fiduciario",
        r_fr: "Non-conformités dans la gestion financière des sous-récipiendaires",
        r_en: "Non-compliances in sub-recipient financial management", r_es: "Incumplimientos en la gestión financiera de los subreceptores",
        pi: s.L(lang, "Modérée × Élevé", "Moderate × High", "Moderada × Alto"),
        m_fr: "Audits annuels, formation continue, manuel de procédures partagé.",
        m_en: "Annual audits, ongoing training, shared procedures manual.", m_es: "Auditorías anuales, formación continua, manual de procedimientos compartido." },
      { cat_fr: "Environnemental & social", cat_en: "Environmental & Social", cat_es: "Ambiental y social",
        r_fr: "Conflits d'usage liés aux ouvrages d'infrastructure",
        r_en: "Land-use conflicts linked to infrastructure works", r_es: "Conflictos de uso vinculados a las obras de infraestructura",
        pi: s.L(lang, "Modérée × Modéré", "Moderate × Moderate", "Moderada × Moderado"),
        m_fr: "Consultations préalables, plan de réinstallation conforme NES AFD.",
        m_en: "Prior consultations, resettlement plan compliant with AFD ESS.", m_es: "Consultas previas, plan de reasentamiento conforme a las NAS de la AFD." },
      { cat_fr: "Contexte", cat_en: "Context", cat_es: "Contexto",
        r_fr: "Instabilité sécuritaire dans certaines zones d'intervention",
        r_en: "Security instability in some intervention zones", r_es: "Inestabilidad en materia de seguridad en algunas zonas de intervención",
        pi: s.L(lang, "Variable", "Variable"),
        m_fr: "Plans de continuité, partenariats locaux, suivi sécuritaire mensuel.",
        m_en: "Business continuity plans, local partnerships, monthly security tracking.", m_es: "Planes de continuidad, alianzas locales, seguimiento de seguridad mensual." },
      { cat_fr: "Climatique", cat_en: "Climate", cat_es: "Climático",
        r_fr: "Aléas climatiques (inondations, sécheresses) affectant les sites",
        r_en: "Climate hazards (floods, droughts) affecting sites", r_es: "Riesgos climáticos (inundaciones, sequías) que afectan a los sitios",
        pi: s.L(lang, "Modérée × Élevé", "Moderate × High", "Moderada × Alto"),
        m_fr: "Études de vulnérabilité, infrastructure résiliente, assurance climatique.",
        m_en: "Vulnerability assessments, resilient infrastructure, climate insurance.", m_es: "Estudios de vulnerabilidad, infraestructura resiliente, seguro climático." },
    ];
    risks.forEach((r) => rows.push(Row([
      Cell(s.L(lang, r.cat_fr, r.cat_en), { width: 1800, size: 18 }),
      Cell(s.L(lang, r.r_fr, r.r_en),     { width: 2800, size: 18 }),
      Cell(r.pi,                           { width: 1800, size: 18, align: window.docx.AlignmentType.CENTER }),
      Cell(s.L(lang, r.m_fr, r.m_en),     { width: 2960, size: 18 }),
    ])));
    out.push(Tbl(rows, { columnWidths: [1800, 2800, 1800, 2960] }));

    return out;
  }

  function buildMissionPlan({ lang }) {
    const s = _shared();
    const { H, P, PageBreak } = s;
    const out = [];
    out.push(PageBreak());
    out.push(H(1, s.L(lang, "7. Plan de mission / supervision", "7. Mission / Supervision Plan", "7. Plan de misión / supervisión"), { color: AFD_COLOR }));
    out.push(P(s.L(lang,
      "Le plan de mission précise les visites de supervision conjointes prévues entre l'AFD et le Maître d'Ouvrage. Il s'articule autour de revues techniques semestrielles, de missions de terrain et de revues de mi-parcours.",
      "The mission plan specifies the joint supervision visits planned between AFD and the project owner. It is structured around bi-annual technical reviews, field missions, and mid-term reviews.", "El plan de misión precisa las visitas de supervisión conjunta previstas entre la AFD y la Entidad Contratante. Se estructura en torno a revisiones técnicas semestrales, misiones de campo y revisiones de medio término.")));
    out.push(P("• " + s.L(lang, "Mission de lancement (T0)", "Inception mission (T0)", "Misión de lanzamiento (T0)")));
    out.push(P("• " + s.L(lang, "Revue technique semestrielle (T+6m, T+12m, …)", "Bi-annual technical review (T+6m, T+12m, …)", "Revisión técnica semestral (T+6m, T+12m, …)")));
    out.push(P("• " + s.L(lang, "Missions de terrain ciblées (selon risques identifiés)", "Targeted field missions (per identified risks)", "Misiones de campo focalizadas (según los riesgos identificados)")));
    out.push(P("• " + s.L(lang, "Revue de mi-parcours (T+18m ou 50 % d'exécution)", "Mid-term review (T+18m or 50 % execution)", "Revisión de medio término (T+18m o 50 % de ejecución)")));
    out.push(P("• " + s.L(lang, "Mission d'achèvement et rapport final", "Closing mission and final report", "Misión de cierre e informe final")));
    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(...buildProjectSummary({ projects, scopeLabel, lang }));
    children.push(...buildLogframe({ indicators, lang }));
    children.push(...buildPerformance({ indicators, year, lang }));
    children.push(...buildProgress({ lang }));
    children.push(...buildBudget({ lang }));
    children.push(...buildRisks({ lang }));
    children.push(...buildMissionPlan({ lang }));
    return new Document({
      creator: "MELR",
      title: "AFD Report — " + (scopeLabel || "Projet") + " — " + year,
      description: "AFD 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 }, // A4
          },
        },
        footers: {
          default: new Footer({
            children: [new Paragraph({
              alignment: AlignmentType.CENTER,
              children: [
                new TextRun({ text: "AFD · " + (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 exportAfdReport(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 || ("AFD-Rapport-" + (args.year || new Date().getFullYear()))), args.lang);
    } catch (e) {
      console.error("[AFD export]", e);
      alert(((args.lang || "fr") === "fr" ? "Erreur AFD : " : "AFD error: ") + e.message);
    }
  }
  window.exportAfdReport = exportAfdReport;
})();
