/* global React */
// ============================================================================
// EX-ANTE REPORT — printable + Word-exportable document
// ============================================================================
// Renders the entire ex-ante dossier as a structured document, formatted for:
//   1. Print-to-PDF (Ctrl+P) — print CSS at the bottom hides the rest of the
//      UI and lays out one continuous A4-styled document.
//   2. Word export — same HTML is downloaded as a .doc file (MIME
//      application/msword); Word opens HTML-based .doc files natively.
//
// All data is read from the live engine results passed as props — no database
// reads here, so the report is always a snapshot of what the user sees.
// Structure follows the standard ex-ante appraisal methodology.

(function () {
  const { useState: useStateR } = React;

  function fmtCurrency(v, ccy) {
    if (v == null || !isFinite(v)) return "—";
    return Math.round(v).toLocaleString() + " " + (ccy || "EUR");
  }
  function fmtPct(v) {
    if (v == null || !isFinite(v)) return "—";
    return (v * 100).toFixed(1) + "%";
  }
  function fmtRatio(v) {
    if (v == null || !isFinite(v)) return "—";
    if (v >= 999) return "∞";
    return Number(v).toFixed(2);
  }
  function fmtNum(v) {
    if (v == null || !isFinite(v)) return "—";
    return Math.round(v).toLocaleString();
  }
  function safeText(v) { return v == null || v === "" ? "—" : v; }

  // ------------------------------------------------------------------------
  // Threshold helpers — uniform color logic shared with the app's tiles
  // so the report visually matches what users see in the live dashboards.
  // ------------------------------------------------------------------------
  function tileColor(value, threshold, dir) {
    // dir = ">" (value must exceed threshold to be ok) or "<" (must be below)
    // Returns one of: "ok" | "bad" | "neutral"
    if (value == null || !isFinite(value)) return "neutral";
    if (dir === "<") return value <= threshold ? "ok" : "bad";
    return value >= threshold ? "ok" : "bad";
  }
  const COLORS = {
    ok:      { fg: "#15803d", bg: "#dcfce7", border: "#86efac" },
    bad:     { fg: "#b91c1c", bg: "#fee2e2", border: "#fca5a5" },
    amber:   { fg: "#a16207", bg: "#fef3c7", border: "#fcd34d" },
    neutral: { fg: "#374151", bg: "#f3f4f6", border: "#d1d5db" },
    accent:  { fg: "#1e3a8a", bg: "#e0e7ff", border: "#a5b4fc" },
  };

  // ------------------------------------------------------------------------
  // Sensitivity heatmap — interpolate green↔red around the threshold so a
  // user can spot bankability cliffs at a glance.
  // ------------------------------------------------------------------------
  function heatmapColor(value, threshold, dir) {
    if (value == null || !isFinite(value)) return COLORS.neutral.bg;
    // Distance from threshold, normalised to [-1, 1]
    let delta;
    if (dir === "<") delta = (threshold - value) / Math.max(Math.abs(threshold), 1);
    else delta = (value - threshold) / Math.max(Math.abs(threshold), 1);
    // Clamp
    delta = Math.max(-1, Math.min(1, delta));
    // Below threshold → red; above → green. Use simple lerp on three control points.
    if (delta >= 0) {
      // pale → strong green
      const t = Math.min(1, delta * 1.2);
      return `rgba(34, 197, 94, ${0.10 + t * 0.30})`;
    }
    const t = Math.min(1, -delta * 1.2);
    return `rgba(220, 38, 38, ${0.10 + t * 0.30})`;
  }

  // Visual KPI tile (HTML)
  function KpiTile({ label, value, sub, status }) {
    const c = COLORS[status || "neutral"];
    return (
      <div style={{
        border: `1px solid ${c.border}`, background: c.bg, color: c.fg,
        borderRadius: 6, padding: "10px 12px",
        display: "flex", flexDirection: "column", gap: 2, minHeight: 70,
      }}>
        <div style={{ fontSize: 9.5, fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.04em", opacity: 0.8 }}>{label}</div>
        <div style={{ fontSize: 18, fontWeight: 700, fontFamily: "Consolas, monospace", letterSpacing: "-0.01em" }}>{value}</div>
        {sub && <div style={{ fontSize: 10, opacity: 0.75 }}>{sub}</div>}
      </div>
    );
  }

  // Decision pill (CONSISTENT / WITH OBS / REJECT)
  function DecisionPill({ decision, lang }) {
    const cfg = decision === "consistent" ? COLORS.ok
              : decision === "with_observations" ? COLORS.amber
              : COLORS.bad;
    const label = decision === "consistent" ? (window.L("CONSISTENT", "CONSISTENT", "CONSISTENTE"))
                : decision === "with_observations" ? (window.L("AVEC OBSERVATIONS", "WITH OBSERVATIONS", "CON OBSERVACIONES"))
                : (window.L("REJET", "REJECT", "RECHAZO"));
    return (
      <span style={{
        display: "inline-block", padding: "2px 8px", borderRadius: 999,
        background: cfg.bg, color: cfg.fg, border: `1px solid ${cfg.border}`,
        fontSize: 10, fontWeight: 700, marginLeft: 6,
      }}>{label}</span>
    );
  }

  // ------------------------------------------------------------------------
  // Inline styles — kept in JS so the .doc export carries them in-line and
  // Word renders the document correctly.
  // ------------------------------------------------------------------------
  const styles = {
    body: { fontFamily: "Calibri, Arial, sans-serif", color: "#111", padding: 32, maxWidth: 900, margin: "0 auto", background: "white", fontSize: 12 },
    cover: { textAlign: "center", marginBottom: 60, paddingTop: 80 },
    coverTitle: { fontSize: 28, fontWeight: 700, marginBottom: 8 },
    coverSub: { fontSize: 14, color: "#555", marginBottom: 30 },
    coverMeta: { fontSize: 12, color: "#666", lineHeight: 1.6 },
    h1: { fontSize: 22, fontWeight: 700, color: "#1f2937", marginTop: 32, marginBottom: 12, borderBottom: "2px solid #1f2937", paddingBottom: 6 },
    h2: { fontSize: 16, fontWeight: 600, color: "#374151", marginTop: 18, marginBottom: 8 },
    h3: { fontSize: 13, fontWeight: 600, color: "#4b5563", marginTop: 12, marginBottom: 6 },
    p: { fontSize: 11, lineHeight: 1.5, marginBottom: 6 },
    table: { width: "100%", borderCollapse: "collapse", marginBottom: 12, fontSize: 11 },
    th: { borderBottom: "2px solid #1f2937", textAlign: "left", padding: "6px 8px", fontWeight: 700, background: "#f9fafb" },
    td: { borderBottom: "1px solid #e5e7eb", padding: "5px 8px", verticalAlign: "top" },
    numTd: { textAlign: "right", fontFamily: "Consolas, monospace" },
    kv: { display: "grid", gridTemplateColumns: "200px 1fr", gap: 8, marginBottom: 4, fontSize: 11 },
    kvLabel: { color: "#6b7280", fontSize: 10.5, textTransform: "uppercase", letterSpacing: "0.04em" },
    decisionBanner: (color) => ({
      padding: 20, borderRadius: 8, border: "2px solid " + color,
      background: color + "20", marginBottom: 18, textAlign: "center",
    }),
    decisionLabel: (color) => ({ fontSize: 24, fontWeight: 800, color }),
    pageBreak: { pageBreakBefore: "always", display: "block" },
  };

  // ------------------------------------------------------------------------
  // Hook: compute chart PNG dataURLs from the live computed data.
  // ------------------------------------------------------------------------
  function useExanteChartImages({ lang, inputs, scen, exanteComputed, mprResult, externalities, capexLines, opexLines, revenueLines, finSources, mprTransfers }) {
    const [charts, setCharts] = React.useState({});
    React.useEffect(() => {
      if (!window.exanteCharts || !window.exanteEngine) return;
      const E = window.exanteEngine;
      const ccy = (inputs && inputs.currency) || "EUR";

      // Cashflow chart inputs
      const cf = exanteComputed && exanteComputed.cashFlow;
      const cashflowOpts = cf ? {
        fcfProject: cf.fcfProject, cumProject: cf.cumProject,
        fcfEquity: cf.fcfEquity, cumEquity: cf.cumEquity,
        ccy,
      } : null;

      // P&L chart inputs
      const plOpts = (exanteComputed && exanteComputed.pl && exanteComputed.pl.length) ? exanteComputed.pl : null;

      // Donut: build from externalities by category — represents how much
      // value goes to each beneficiary category (positive externalities).
      let donutOpts = null;
      if (externalities && externalities.length > 0) {
        const buckets = {};
        externalities.filter((e) => e.kind === "positive").forEach((e) => {
          const k = e.category || "other";
          buckets[k] = (buckets[k] || 0) + (Number(e.amount_year1) || 0);
        });
        const catLabel = (k) => {
          const E = window.exanteEngine;
          if (E && typeof E.exLabel === "function") return E.exLabel("extCat", k, lang);
          return k;
        };
        const arr = Object.entries(buckets).map(([name, value]) => ({ name: catLabel(name), value }));
        if (arr.length > 0) donutOpts = { stakeholders: arr };
      }

      // Sensitivity matrix — re-runs the engine, can be slow if many lines
      let sensitivityOpts = null;
      try {
        const baseOpts = {
          inputs, scen,
          capexLines: capexLines || [], opexLines: opexLines || [],
          revenueLines: revenueLines || [], financingSources: finSources || [],
        };
        const mprBaseOpts = {
          inputs, capexLines: capexLines || [],
          opexByYear: exanteComputed && exanteComputed.opexByYear,
          revenueByYear: exanteComputed && exanteComputed.revenueByYear,
          debtSchedule: exanteComputed && exanteComputed.debt,
          mprTransfers: mprTransfers || [], externalities: externalities || [],
          conversionFactors: null,
        };
        const variables = [
          { v: "capex",    fr: "CAPEX",                en: "CAPEX", es: "CAPEX" },
          { v: "volumes",  fr: "Volumes",              en: "Volumes", es: "Volúmenes" },
          { v: "tariffs",  fr: "Tarifs",               en: "Tariffs", es: "Tarifas" },
          { v: "opex",     fr: "OPEX",                 en: "OPEX", es: "OPEX" },
          { v: "discount", fr: "Taux d'actualisation", en: "Discount rate", es: "Tasa de descuento" },
        ];
        const deltas = [-0.20, -0.10, 0, 0.10, 0.20];
        if (cf) {
          const matrix = variables.map((v) => ({
            v,
            cells: deltas.map((d) => E.economicSensitivityShock(baseOpts, mprBaseOpts, v.v, d)),
          }));
          sensitivityOpts = { matrix, variables, deltas };
        }
      } catch (e) { /* leave null */ }

      (async () => {
        const urls = await window.exanteCharts.dataURLs({
          cashflow: cashflowOpts,
          pl: plOpts,
          donut: donutOpts,
          sensitivity: sensitivityOpts,
          ccy,
        });
        setCharts(urls || {});
      })();
    // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [JSON.stringify({
      cap: (capexLines || []).length,
      opx: (opexLines || []).length,
      rev: (revenueLines || []).length,
      fin: (finSources || []).length,
      ext: (externalities || []).length,
      tra: (mprTransfers || []).length,
      sc: inputs && inputs.scenario,
    })]);
    return charts;
  }

  // ------------------------------------------------------------------------
  // The report component
  // ------------------------------------------------------------------------
  function ExanteReport({ lang, dossier, ident, inputs, scen, calendar, capexLines, opexLines, revenueLines, finSources, pubTransfers, mprTransfers, externalities, qualityItems, mcItems, stakeholders, stakeholderAccounts, conversionFactors, institutional, exanteComputed, mprResult, qualityResult, mcResult, finalDecision, reportTornado, reportScenarios, reportReco, reportTornadoUnit }) {
    const chartImages = useExanteChartImages({
      lang, inputs, scen, exanteComputed, mprResult, externalities,
      capexLines, opexLines, revenueLines, finSources, mprTransfers,
    });
    const ccy = (inputs && inputs.currency) || "EUR";
    const projectName = (dossier && dossier.projects && dossier.projects.code) || (ident && ident.intitule) || "—";
    const t = (fr, en, es) => lang === "es" ? (es != null ? es : en) : lang === "en" ? en : fr;
    // Traduit une clé d'énumération (catégorie, type…) en libellé FR/EN via la
    // table partagée du moteur. Repli sur la clé brute si absente.
    const xL = (group, value) => {
      const E = window.exanteEngine;
      if (E && typeof E.exLabel === "function") return E.exLabel(group, value, lang);
      return value == null || value === "" ? "—" : String(value);
    };
    const today = new Date().toLocaleDateString(window.L("fr-FR", "en-US", "es-ES"), { year: "numeric", month: "long", day: "numeric" });

    const decisionUi = finalDecision ? {
      go:          { color: "#16a34a", label: t("GO — APPROUVÉ POUR FINANCEMENT", "GO — APPROVED FOR FUNDING", "GO — APROBADO PARA FINANCIAMIENTO") },
      conditional: { color: "#d97706", label: t("CONDITIONNEL — AVEC OBSERVATIONS", "CONDITIONAL — WITH OBSERVATIONS", "CONDICIONAL — CON OBSERVACIONES") },
      no_go:       { color: "#dc2626", label: t("NO-GO — À RÉVISER OU REJETER", "NO-GO — TO REVISE OR REJECT", "NO-GO — A REVISAR O RECHAZAR") },
    }[finalDecision.decision] : null;

    return (
      <div style={styles.body} className="exante-report-body">
        {/* ===== COVER PAGE ===== */}
        <div style={styles.cover}>
          <div style={styles.coverTitle}>
            {t("Évaluation ex ante", "Ex-ante appraisal", "Evaluación ex ante")}
          </div>
          <div style={styles.coverSub}>
            {safeText(ident && ident.intitule)}
          </div>
          <div style={styles.coverMeta}>
            {t("Code projet : ", "Project code: ", "Código del proyecto: ")}{projectName}<br />
            {t("Tutelle : ", "Authority: ", "Autoridad de tutela: ")}{safeText(ident && ident.ministry)}<br />
            {t("Date d'élaboration : ", "Drafted on: ", "Fecha de elaboración: ")}{safeText(ident && ident.elaboration_date)}<br />
            {t("Document généré le : ", "Document generated on: ", "Documento generado el: ")}{today}<br />
            <br />
            <small>{t("Évaluation ex ante des projets et programmes", "Ex-ante appraisal of projects and programmes", "Evaluación ex ante de proyectos y programas")}</small>
          </div>
        </div>

        {/* ===== FINAL DECISION BANNER ===== */}
        {decisionUi && (
          <div style={styles.decisionBanner(decisionUi.color)}>
            <div style={styles.decisionLabel(decisionUi.color)}>{decisionUi.label}</div>
            <div style={{ fontSize: 12, color: "#374151", marginTop: 8 }}>
              {finalDecision.reasons.map((r) => typeof r === "string" ? r : ((lang === "es" ? (r.es != null ? r.es : r.en) : lang === "fr" ? r.fr : r.en))).join(" · ")}
            </div>
          </div>
        )}

        {/* ===== EXECUTIVE SUMMARY ===== */}
        <h1 style={styles.h1}>{t("I. Synthèse exécutive", "I. Executive summary", "I. Síntesis ejecutiva")}</h1>
        <div style={styles.kv}>
          <span style={styles.kvLabel}>{t("Objectif général", "General objective", "Objetivo general")}</span>
          <span>{safeText(ident && ident.general_objective)}</span>
        </div>
        <div style={styles.kv}>
          <span style={styles.kvLabel}>{t("Coût global", "Global cost", "Costo global")}</span>
          <span>{fmtCurrency(ident && ident.global_cost_native, ident && ident.currency)}</span>
        </div>
        <div style={styles.kv}>
          <span style={styles.kvLabel}>{t("Horizon total", "Total horizon", "Horizonte total")}</span>
          <span>{(ident && ident.total_horizon_years) || "—"} {t("ans", "yrs", "años")}</span>
        </div>
        <div style={styles.kv}>
          <span style={styles.kvLabel}>{t("Bénéficiaires directs", "Direct beneficiaries", "Beneficiarios directos")}</span>
          <span>{safeText(ident && ident.direct_targets)} ({(ident && ident.direct_target_size) ? Number(ident.direct_target_size).toLocaleString() : "—"})</span>
        </div>
        {exanteComputed && exanteComputed.indicators && (
          (() => {
            const ind = exanteComputed.indicators;
            const discFin = (inputs && inputs.discount_rate_financial) || 0.09;
            const discEco = (inputs && inputs.discount_rate_economic)  || 0.09;
            const tiles = [
              { label: "VAN " + t("projet", "project", "proyecto"), value: fmtCurrency(ind.npvProject, ccy), status: tileColor(ind.npvProject, 0, ">"), sub: "≥ 0" },
              { label: "TRI " + t("projet", "project", "proyecto"), value: fmtPct(ind.irrProject), status: tileColor(ind.irrProject, discFin, ">"), sub: "> " + fmtPct(discFin) },
              { label: t("DSCR min", "Min DSCR", "DSCR mín."), value: fmtRatio(ind.dscrMin), status: tileColor(ind.dscrMin, 1.2, ">"), sub: "≥ 1,2" },
              { label: t("Marge EBITDA moy.", "Avg EBITDA margin", "Margen EBITDA prom."), value: fmtPct(ind.ebitdaMarginAvg), status: tileColor(ind.ebitdaMarginAvg, 0, ">"), sub: t("Sur l'horizon", "Over horizon", "Sobre el horizonte") },
            ];
            if (mprResult && mprResult.indicators) {
              tiles.push(
                { label: "ENPV", value: fmtCurrency(mprResult.indicators.enpv, ccy), status: tileColor(mprResult.indicators.enpv, 0, ">"), sub: "≥ 0" },
                { label: "EIRR", value: fmtPct(mprResult.indicators.eirr), status: tileColor(mprResult.indicators.eirr, discEco, ">"), sub: "> " + fmtPct(discEco) },
                { label: t("Ratio B/C", "B/C ratio", "Ratio B/C"), value: fmtRatio(mprResult.indicators.bcRatio), status: tileColor(mprResult.indicators.bcRatio, 1, ">"), sub: "≥ 1" }
              );
            }
            if (qualityResult) tiles.push({ label: t("Qualité", "Quality", "Calidad"), value: fmtPct(qualityResult.pct), status: tileColor(qualityResult.pct, 0.6, ">"), sub: "≥ 60%" });
            if (mcResult)      tiles.push({ label: t("Multicritère", "Multi-criteria", "Multicriterio"), value: fmtPct(mcResult.globalPct), status: tileColor(mcResult.globalPct, 0.75, ">"), sub: "≥ 75%" });
            return (
              <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 8, margin: "10px 0 16px" }}>
                {tiles.map((tile, i) => <KpiTile key={i} {...tile} />)}
              </div>
            );
          })()
        )}

        {/* Cashflow chart at the bottom of the executive summary */}
        {chartImages.cashflow && (
          <div style={{ marginTop: 14 }}>
            <img src={chartImages.cashflow} alt="Cashflow chart" style={{ width: "100%", maxWidth: 700, display: "block", margin: "0 auto" }} />
          </div>
        )}

        {/* ===== II. IDENTIFICATION ===== */}
        <div style={styles.pageBreak}></div>
        <h1 style={styles.h1}>{t("II. Identification du projet (Tableau 8)", "II. Project identification (Table 8)", "II. Identificación del proyecto (Tabla 8)")}</h1>
        {ident && (
          <>
            <h2 style={styles.h2}>{t("1. Identification générale", "1. General identification", "1. Identificación general")}</h2>
            <div style={styles.kv}><span style={styles.kvLabel}>{t("Intitulé", "Title", "Título")}</span><span>{safeText(ident.intitule)}</span></div>
            <div style={styles.kv}><span style={styles.kvLabel}>{t("Sous-secteur", "Sub-sector", "Subsector")}</span><span>{safeText(ident.sub_sector)}</span></div>
            <div style={styles.kv}><span style={styles.kvLabel}>{t("Ministère", "Ministry", "Ministerio")}</span><span>{safeText(ident.ministry)}</span></div>
            <div style={styles.kv}><span style={styles.kvLabel}>{t("Devise", "Currency", "Moneda")}</span><span>{safeText(ident.currency)}</span></div>

            <h2 style={styles.h2}>{t("2. Localisation et durée", "2. Location and duration", "2. Localización y duración")}</h2>
            <div style={styles.kv}><span style={styles.kvLabel}>{t("Zone", "Zone", "Zona")}</span><span>{safeText(ident.zone)}</span></div>
            <div style={styles.kv}><span style={styles.kvLabel}>{t("Phase investissement", "Investment phase", "Fase de inversión")}</span><span>{ident.investment_duration_years || "—"} {t("ans", "yrs", "años")}</span></div>
            <div style={styles.kv}><span style={styles.kvLabel}>{t("Phase exploitation", "Operation phase", "Fase de explotación")}</span><span>{ident.operation_duration_years || "—"} {t("ans", "yrs", "años")}</span></div>

            <h2 style={styles.h2}>{t("3. Ancrage stratégique", "3. Strategic anchoring", "3. Anclaje estratégico")}</h2>
            <div style={styles.kv}><span style={styles.kvLabel}>{t("Plan", "Plan", "Plan")}</span><span>{safeText(ident.strategy_plan)}</span></div>
            <div style={styles.kv}><span style={styles.kvLabel}>{t("Axe", "Axis", "Eje")}</span><span>{safeText(ident.strategic_axis)}</span></div>
            <div style={styles.kv}><span style={styles.kvLabel}>{t("Politique sectorielle", "Sectoral policy", "Política sectorial")}</span><span>{safeText(ident.sectoral_policy)}</span></div>

            <h2 style={styles.h2}>{t("4. Situation initiale et problème", "4. Initial situation and problem", "4. Situación inicial y problema")}</h2>
            <p style={styles.p}><b>{t("Situation initiale : ", "Initial situation: ", "Situación inicial: ")}</b>{safeText(ident.initial_situation)}</p>
            <p style={styles.p}><b>{t("Sans projet : ", "Without project: ", "Sin proyecto: ")}</b>{safeText(ident.without_project_situation)}</p>
            <p style={styles.p}><b>{t("Problème central : ", "Central problem: ", "Problema central: ")}</b>{safeText(ident.central_problem)}</p>
            <p style={styles.p}><b>{t("Principales contraintes : ", "Main constraints: ", "Principales restricciones: ")}</b>{safeText(ident.main_constraints)}</p>

            <h2 style={styles.h2}>{t("5. Objectifs", "5. Objectives", "5. Objetivos")}</h2>
            <p style={styles.p}><b>{t("Objectif général : ", "General objective: ", "Objetivo general: ")}</b>{safeText(ident.general_objective)}</p>
            {ident.specific_objective_1 && <p style={styles.p}>OS 1 : {ident.specific_objective_1}</p>}
            {ident.specific_objective_2 && <p style={styles.p}>OS 2 : {ident.specific_objective_2}</p>}
            {ident.specific_objective_3 && <p style={styles.p}>OS 3 : {ident.specific_objective_3}</p>}
            {ident.specific_objective_4 && <p style={styles.p}>OS 4 : {ident.specific_objective_4}</p>}

            <h2 style={styles.h2}>{t("6. Composantes", "6. Components", "6. Componentes")}</h2>
            <table style={styles.table}>
              <thead><tr><th style={styles.th}>{t("Composante", "Component", "Componente")}</th><th style={{ ...styles.th, ...styles.numTd }}>{t("Budget", "Budget", "Presupuesto")}</th></tr></thead>
              <tbody>
                {[1,2,3,4,5,6].map((i) => ident["component_" + i + "_label"] && (
                  <tr key={i}>
                    <td style={styles.td}>{ident["component_" + i + "_label"]}</td>
                    <td style={{ ...styles.td, ...styles.numTd }}>{fmtCurrency(ident["component_" + i + "_amount"], ident.currency)}</td>
                  </tr>
                ))}
              </tbody>
            </table>

            <h2 style={styles.h2}>{t("7. Risques et conditions", "7. Risks and preconditions", "7. Riesgos y condiciones")}</h2>
            <p style={styles.p}><b>{t("Risques : ", "Risks: ", "Riesgos: ")}</b>{safeText(ident.main_risks)}</p>
            <p style={styles.p}><b>{t("Conditions préalables : ", "Preconditions: ", "Condiciones previas: ")}</b>{safeText(ident.preconditions)}</p>
          </>
        )}

        {/* ===== III. INPUTS & SCENARIOS ===== */}
        <div style={styles.pageBreak}></div>
        <h1 style={styles.h1}>{t("III. Paramètres et scénarios", "III. Parameters and scenarios", "III. Parámetros y escenarios")}</h1>
        {inputs && (
          <table style={styles.table}>
            <thead><tr><th style={styles.th}>{t("Paramètre", "Parameter", "Parámetro")}</th><th style={styles.th}>{t("Valeur", "Value", "Valor")}</th></tr></thead>
            <tbody>
              <tr><td style={styles.td}>{t("Scénario actif", "Active scenario", "Escenario activo")}</td><td style={styles.td}>{inputs.scenario}</td></tr>
              <tr><td style={styles.td}>{t("Horizon", "Horizon", "Horizonte")}</td><td style={styles.td}>{inputs.horizon_years} {t("ans", "yrs", "años")}</td></tr>
              <tr><td style={styles.td}>{t("Taux d'actualisation financier", "Financial discount rate", "Tasa de actualización financiera")}</td><td style={styles.td}>{fmtPct(inputs.discount_rate_financial)}</td></tr>
              <tr><td style={styles.td}>{t("Taux d'actualisation économique", "Economic discount rate", "Tasa de actualización económica")}</td><td style={styles.td}>{fmtPct(inputs.discount_rate_economic)}</td></tr>
              <tr><td style={styles.td}>{t("Inflation annuelle", "Annual inflation", "Inflación anual")}</td><td style={styles.td}>{fmtPct(inputs.inflation_annual)}</td></tr>
              <tr><td style={styles.td}>{t("Taux d'impôt effectif", "Effective tax rate", "Tasa impositiva efectiva")}</td><td style={styles.td}>{fmtPct(inputs.tax_rate_effective)}</td></tr>
              <tr><td style={styles.td}>{t("Part dette / CAPEX", "Debt / CAPEX share", "Parte deuda / CAPEX")}</td><td style={styles.td}>{fmtPct(inputs.debt_share_capex)}</td></tr>
              <tr><td style={styles.td}>{t("Taux d'intérêt dette", "Debt interest rate", "Tasa de interés de la deuda")}</td><td style={styles.td}>{fmtPct(inputs.debt_interest_rate)}</td></tr>
              <tr><td style={styles.td}>{t("Imprévus CAPEX", "Contingencies", "Imprevistos CAPEX")}</td><td style={styles.td}>{fmtPct(inputs.contingencies_capex)}</td></tr>
            </tbody>
          </table>
        )}

        {/* ===== IV. CALENDAR ===== */}
        {calendar && calendar.phases && calendar.phases.length > 0 && (
          <>
            <h2 style={styles.h2}>{t("Calendrier (phases & actions)", "Schedule (phases & actions)", "Calendario (fases y acciones)")}</h2>
            <table style={styles.table}>
              <thead><tr>
                <th style={styles.th}>{t("Phase", "Phase", "Fase")}</th>
                <th style={styles.th}>{t("Action", "Action", "Acción")}</th>
                <th style={styles.th}>{t("Début", "Start", "Inicio")}</th>
                <th style={styles.th}>{t("Fin", "End", "Fin")}</th>
                <th style={{ ...styles.th, ...styles.numTd }}>%</th>
              </tr></thead>
              <tbody>
                {(calendar.activities || []).map((a) => {
                  const ph = calendar.phases.find((p) => p.id === a.phase_id);
                  return (
                    <tr key={a.id}>
                      <td style={styles.td}>{ph ? ph.name_fr : "—"}</td>
                      <td style={styles.td}>{a.milestone ? "◆ " : ""}{a.name_fr}</td>
                      <td style={styles.td}>{a.start_date || "—"}</td>
                      <td style={styles.td}>{a.end_date || "—"}</td>
                      <td style={{ ...styles.td, ...styles.numTd }}>{a.progress || 0}%</td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
            {(calendar.activities || []).length > 0 && (() => {
              const g = window.melr && window.melr.exanteGanttDataUrl
                ? window.melr.exanteGanttDataUrl(calendar, lang)
                : null;
              return g && g.url ? (
                <div style={{ marginTop: 10 }}>
                  <h2 style={styles.h2}>{t("Diagramme de Gantt", "Gantt chart", "Diagrama de Gantt")}</h2>
                  <img src={g.url} alt="Gantt" style={{ width: "100%", maxWidth: 1000, display: "block", border: "1px solid #e5e7eb", borderRadius: 4 }} />
                </div>
              ) : null;
            })()}
          </>
        )}

        {/* ===== V. CAPEX ===== */}
        <div style={styles.pageBreak}></div>
        <h1 style={styles.h1}>{t("IV. Analyse financière", "IV. Financial analysis", "IV. Análisis financiero")}</h1>
        <h2 style={styles.h2}>{t("CAPEX — Investissements (Tableau 13)", "CAPEX — Investments (Table 13)", "CAPEX — Inversiones (Tabla 13)")}</h2>
        {capexLines && capexLines.length > 0 ? (
          <table style={styles.table}>
            <thead><tr>
              <th style={styles.th}>{t("Rubrique", "Item", "Rubro")}</th>
              <th style={styles.th}>{t("Catégorie", "Category", "Categoría")}</th>
              <th style={{ ...styles.th, ...styles.numTd }}>{t("Qté", "Qty", "Cant.")}</th>
              <th style={{ ...styles.th, ...styles.numTd }}>{t("Coût unit.", "Unit cost", "Costo unit.")}</th>
              <th style={{ ...styles.th, ...styles.numTd }}>{t("Total", "Total", "Total")}</th>
              <th style={{ ...styles.th, ...styles.numTd }}>{t("Amort. (ans)", "Amort. (yrs)", "Amort. (años)")}</th>
            </tr></thead>
            <tbody>
              {capexLines.map((l) => (
                <tr key={l.id}>
                  <td style={styles.td}>{l.rubric}</td>
                  <td style={styles.td}>{xL("capexCat", l.category)}</td>
                  <td style={{ ...styles.td, ...styles.numTd }}>{Number(l.quantity || 1).toLocaleString()}</td>
                  <td style={{ ...styles.td, ...styles.numTd }}>{fmtNum(l.unit_cost)}</td>
                  <td style={{ ...styles.td, ...styles.numTd, fontWeight: 600 }}>{fmtNum((l.quantity || 1) * (l.unit_cost || 0))}</td>
                  <td style={{ ...styles.td, ...styles.numTd }}>{l.amort_years || "—"}</td>
                </tr>
              ))}
              {exanteComputed && exanteComputed.capex && (
                <>
                  <tr><td colSpan="4" style={{ ...styles.td, textAlign: "right", fontWeight: 600 }}>{t("Sous-total", "Subtotal", "Subtotal")}</td><td style={{ ...styles.td, ...styles.numTd, fontWeight: 600 }}>{fmtNum(exanteComputed.capex.subtotal)}</td><td style={styles.td}></td></tr>
                  <tr><td colSpan="4" style={{ ...styles.td, textAlign: "right" }}>{t("Imprévus", "Contingencies", "Imprevistos")}</td><td style={{ ...styles.td, ...styles.numTd }}>{fmtNum(exanteComputed.capex.contingencies)}</td><td style={styles.td}></td></tr>
                  <tr><td colSpan="4" style={{ ...styles.td, textAlign: "right", fontWeight: 700, fontSize: 13 }}>{t("CAPEX TOTAL", "TOTAL CAPEX", "CAPEX TOTAL")}</td><td style={{ ...styles.td, ...styles.numTd, fontWeight: 700, fontSize: 13 }}>{fmtNum(exanteComputed.capex.total)}</td><td style={styles.td}></td></tr>
                </>
              )}
            </tbody>
          </table>
        ) : <p style={styles.p}>{t("(aucune ligne CAPEX)", "(no CAPEX line)", "(ninguna línea CAPEX)")}</p>}

        {/* ===== OPEX ===== */}
        <h2 style={styles.h2}>{t("OPEX — Coûts d'exploitation (Tableau 14)", "OPEX — Operating costs (Table 14)", "OPEX — Costos de explotación (Tabla 14)")}</h2>
        {opexLines && opexLines.length > 0 ? (
          <table style={styles.table}>
            <thead><tr>
              <th style={styles.th}>{t("Rubrique", "Item", "Rubro")}</th>
              <th style={styles.th}>{t("Catégorie", "Category", "Categoría")}</th>
              <th style={{ ...styles.th, ...styles.numTd }}>{t("An 1", "Y1", "Año 1")}</th>
              <th style={{ ...styles.th, ...styles.numTd }}>{t("An 5", "Y5", "Año 5")}</th>
              <th style={{ ...styles.th, ...styles.numTd }}>{t("An 10", "Y10", "Año 10")}</th>
            </tr></thead>
            <tbody>
              {opexLines.map((l) => {
                const series = window.exanteEngine && window.exanteEngine.projectOpexLine(l, 25, inputs, scen);
                return (
                  <tr key={l.id}>
                    <td style={styles.td}>{l.rubric}</td>
                    <td style={styles.td}>{xL("opexCat", l.inflation_category)}</td>
                    <td style={{ ...styles.td, ...styles.numTd }}>{fmtNum(l.year1_amount)}</td>
                    <td style={{ ...styles.td, ...styles.numTd }}>{series ? fmtNum(series[4]) : "—"}</td>
                    <td style={{ ...styles.td, ...styles.numTd }}>{series ? fmtNum(series[9]) : "—"}</td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        ) : <p style={styles.p}>{t("(aucune ligne OPEX)", "(no OPEX line)", "(ninguna línea OPEX)")}</p>}

        {/* ===== Revenue ===== */}
        <h2 style={styles.h2}>{t("Revenus (Tableau 15)", "Revenue (Table 15)", "Ingresos (Tabla 15)")}</h2>
        {revenueLines && revenueLines.length > 0 ? (
          <table style={styles.table}>
            <thead><tr>
              <th style={styles.th}>{t("Rubrique", "Item", "Rubro")}</th>
              <th style={{ ...styles.th, ...styles.numTd }}>{t("Vol. An 1", "Vol. Y1", "Vol. Año 1")}</th>
              <th style={{ ...styles.th, ...styles.numTd }}>{t("Tarif An 1", "Tariff Y1", "Tarifa Año 1")}</th>
              <th style={{ ...styles.th, ...styles.numTd }}>{t("Revenu An 1", "Revenue Y1", "Ingreso Año 1")}</th>
            </tr></thead>
            <tbody>
              {revenueLines.map((l) => (
                <tr key={l.id}>
                  <td style={styles.td}>{l.rubric}</td>
                  <td style={{ ...styles.td, ...styles.numTd }}>{l.is_fixed ? "—" : fmtNum(l.year1_volume)}</td>
                  <td style={{ ...styles.td, ...styles.numTd }}>{fmtNum(l.year1_tariff)}</td>
                  <td style={{ ...styles.td, ...styles.numTd, fontWeight: 600 }}>{fmtNum(l.is_fixed ? l.year1_tariff : (l.year1_volume || 0) * (l.year1_tariff || 0))}</td>
                </tr>
              ))}
            </tbody>
          </table>
        ) : <p style={styles.p}>{t("(aucune ligne de revenu)", "(no revenue line)", "(ninguna línea de ingresos)")}</p>}

        {/* ===== Financing ===== */}
        {/* BFR placé AVANT le plan de financement (ordre Guide DP) */}
        {(() => {
          const per = (exanteComputed && exanteComputed.bfr && exanteComputed.bfr.perYear) || [];
          const dlt = (exanteComputed && exanteComputed.bfr && exanteComputed.bfr.deltas) || [];
          if (!per.length) return null;
          const M = (v) => (v == null || !isFinite(v)) ? "—" : Math.round(v / 1e6).toLocaleString();
          return (
            <>
              <h2 style={styles.h2}>{t("Besoin en fonds de roulement (BFR)", "Working capital requirement (WCR)", "Necesidades operativas de fondos (NOF)")}</h2>
              <p style={{ ...styles.p, fontSize: 10, color: "#6b7280" }}>
                {t("Créances + stocks − dettes fournisseurs (M " + ccy + "). La variation Δ impacte la trésorerie.",
                   "Receivables + inventory − payables (M " + ccy + "). The change Δ affects cash flow.")}
              </p>
              <table style={styles.table}>
                <thead><tr>
                  <th style={styles.th}>{t("Poste", "Item", "Partida")}</th>
                  {per.map((_, i) => <th key={i} style={{ ...styles.th, ...styles.numTd }}>{t("An ", "Y", "Año ")}{i + 1}</th>)}
                </tr></thead>
                <tbody>
                  <tr><td style={styles.td}>{t("Créances clients", "Receivables", "Cuentas por cobrar")}</td>{per.map((p, i) => <td key={i} style={{ ...styles.td, ...styles.numTd }}>{M(p.receivables)}</td>)}</tr>
                  <tr><td style={styles.td}>{t("Stocks / inventaire", "Inventory", "Existencias / inventario")}</td>{per.map((p, i) => <td key={i} style={{ ...styles.td, ...styles.numTd }}>{M(p.inventory)}</td>)}</tr>
                  <tr><td style={styles.td}>{t("Dettes fournisseurs", "Payables", "Cuentas por pagar")}</td>{per.map((p, i) => <td key={i} style={{ ...styles.td, ...styles.numTd }}>{M(p.payables)}</td>)}</tr>
                  <tr><td style={{ ...styles.td, fontWeight: 700 }}>BFR</td>{per.map((p, i) => <td key={i} style={{ ...styles.td, ...styles.numTd, fontWeight: 700 }}>{M(p.bfr)}</td>)}</tr>
                  <tr><td style={styles.td}>Δ BFR</td>{dlt.map((d, i) => <td key={i} style={{ ...styles.td, ...styles.numTd }}>{M(d)}</td>)}</tr>
                </tbody>
              </table>
            </>
          );
        })()}

        <h2 style={styles.h2}>{t("Plan de financement (Tableau 17)", "Financing plan (Table 17)", "Plan de financiamiento (Tabla 17)")}</h2>
        {finSources && finSources.length > 0 ? (
          <table style={styles.table}>
            <thead><tr>
              <th style={styles.th}>{t("Source", "Source", "Fuente")}</th>
              <th style={styles.th}>{t("Nature", "Kind", "Naturaleza")}</th>
              <th style={{ ...styles.th, ...styles.numTd }}>{t("Montant", "Amount", "Importe")}</th>
            </tr></thead>
            <tbody>
              {finSources.map((f) => (
                <tr key={f.id}>
                  <td style={styles.td}>{f.source}</td>
                  <td style={styles.td}>{xL("finKind", f.kind)}</td>
                  <td style={{ ...styles.td, ...styles.numTd }}>{fmtCurrency(f.amount, f.currency)}</td>
                </tr>
              ))}
            </tbody>
          </table>
        ) : <p style={styles.p}>{t("(aucune source)", "(no source)", "(ninguna fuente)")}</p>}

        {/* ===== Financial indicators ===== */}
        {exanteComputed && exanteComputed.indicators && (() => {
          const ind = exanteComputed.indicators;
          const discFin = (inputs && inputs.discount_rate_financial) || 0.09;
          return (
            <>
              <h2 style={styles.h2}>{t("Indicateurs financiers", "Financial indicators", "Indicadores financieros")}</h2>
              <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 8, marginBottom: 12 }}>
                <KpiTile label={t("VAN projet", "Project NPV", "VAN del proyecto")}        value={fmtCurrency(ind.npvProject, ccy)} status={tileColor(ind.npvProject, 0, ">")} sub="≥ 0" />
                <KpiTile label={t("TRI projet", "Project IRR", "TIR del proyecto")}        value={fmtPct(ind.irrProject)} status={tileColor(ind.irrProject, discFin, ">")} sub={"> " + fmtPct(discFin)} />
                <KpiTile label={t("DSCR minimum", "Min DSCR", "DSCR mínimo")}         value={fmtRatio(ind.dscrMin)} status={tileColor(ind.dscrMin, 1.2, ">")} sub="≥ 1,2" />
                <KpiTile label={t("VAN actionnaire", "Equity NPV", "VAN del accionista")}    value={fmtCurrency(ind.npvEquity, ccy)} status={tileColor(ind.npvEquity, 0, ">")} sub="≥ 0" />
                <KpiTile label={t("TRI actionnaire", "Equity IRR", "TIR del accionista")}    value={fmtPct(ind.irrEquity)} status={tileColor(ind.irrEquity, discFin, ">")} sub={"> " + fmtPct(discFin)} />
                <KpiTile label={t("Marge EBITDA moy.", "Avg EBITDA margin", "Margen EBITDA prom.")} value={fmtPct(ind.ebitdaMarginAvg)} status={tileColor(ind.ebitdaMarginAvg, 0, ">")} sub={t("Sur l'horizon", "Over horizon", "Sobre el horizonte")} />
              </div>
            </>
          );
        })()}

        {/* P&L chart */}
        {chartImages.pl && (
          <div style={{ marginTop: 14 }}>
            <img src={chartImages.pl} alt="P&L chart" style={{ width: "100%", maxWidth: 700, display: "block", margin: "0 auto" }} />
          </div>
        )}

        {/* Stakeholder accounts (Phase 7.1) */}
        {stakeholderAccounts && stakeholderAccounts.rows && stakeholderAccounts.rows.length > 0 && (
          <>
            <h2 style={styles.h2}>{t("Comptes par acteur (Tableau 22)", "Stakeholder accounts (Table 22)", "Cuentas por actor (Tabla 22)")}</h2>
            <p style={styles.p}>
              {t("Revenus, coûts et impact net par acteur (avec vs sans projet), cumulés sur l'horizon.",
                 "Revenue, costs and net impact per actor (with vs without project), cumulated over the horizon.", "Ingresos, costos e impacto neto por actor (con vs sin proyecto), acumulados sobre el horizonte.")}
            </p>
            <table style={styles.table}>
              <thead><tr>
                <th style={styles.th}>{t("Acteur", "Stakeholder", "Actor")}</th>
                <th style={{ ...styles.th, ...styles.numTd }}>{t("Bénéf.", "Benef.", "Benef.")}</th>
                <th style={{ ...styles.th, ...styles.numTd }}>{t("Revenu cum.", "Cumul. revenue", "Ingreso acum.")}</th>
                <th style={{ ...styles.th, ...styles.numTd }}>{t("Coût cum.", "Cumul. cost", "Costo acum.")}</th>
                <th style={{ ...styles.th, ...styles.numTd }}>{t("Net (avec)", "Net (with)", "Neto (con)")}</th>
                <th style={{ ...styles.th, ...styles.numTd }}>{t("Net (sans)", "Net (without)", "Neto (sin)")}</th>
                <th style={{ ...styles.th, ...styles.numTd }}>{t("Impact", "Impact", "Impacto")}</th>
              </tr></thead>
              <tbody>
                {stakeholderAccounts.rows.map((r) => (
                  <tr key={r.id}>
                    <td style={{ ...styles.td, fontWeight: 600 }}>{r.name}</td>
                    <td style={{ ...styles.td, ...styles.numTd }}>{r.beneficiary_count}</td>
                    <td style={{ ...styles.td, ...styles.numTd }}>{fmtNum(r.cumWithRevenue)}</td>
                    <td style={{ ...styles.td, ...styles.numTd, color: "#dc2626" }}>({fmtNum(r.cumWithCost)})</td>
                    <td style={{ ...styles.td, ...styles.numTd, fontWeight: 600 }}>{fmtNum(r.cumWithNet)}</td>
                    <td style={{ ...styles.td, ...styles.numTd, color: "#6b7280" }}>{fmtNum(r.cumBaselineNet)}</td>
                    <td style={{
                      ...styles.td, ...styles.numTd, fontWeight: 700,
                      color: r.cumImpact >= 0 ? "#15803d" : "#b91c1c",
                      background: r.cumImpact >= 0 ? "rgba(34,197,94,.08)" : "rgba(220,38,38,.08)",
                    }}>{r.cumImpact >= 0 ? "+" : ""}{fmtNum(r.cumImpact)}</td>
                  </tr>
                ))}
                <tr style={{ background: "#f3f4f6", fontWeight: 700 }}>
                  <td colSpan="2" style={styles.td}>TOTAL</td>
                  <td style={{ ...styles.td, ...styles.numTd }}>{fmtNum(stakeholderAccounts.total.cumWithRevenue)}</td>
                  <td style={{ ...styles.td, ...styles.numTd }}>({fmtNum(stakeholderAccounts.total.cumWithCost)})</td>
                  <td style={{ ...styles.td, ...styles.numTd }}>{fmtNum(stakeholderAccounts.total.cumWithNet)}</td>
                  <td style={{ ...styles.td, ...styles.numTd }}>{fmtNum(stakeholderAccounts.total.cumBaselineNet)}</td>
                  <td style={{
                    ...styles.td, ...styles.numTd,
                    color: stakeholderAccounts.total.cumImpact >= 0 ? "#15803d" : "#b91c1c",
                  }}>{stakeholderAccounts.total.cumImpact >= 0 ? "+" : ""}{fmtNum(stakeholderAccounts.total.cumImpact)}</td>
                </tr>
              </tbody>
            </table>
          </>
        )}

        {/* ===== V. ECONOMIC (MPR) ===== */}
        <div style={styles.pageBreak}></div>
        <h1 style={styles.h1}>{t("V. Analyse économique (MPR)", "V. Economic analysis (MPR)", "V. Análisis económico (MPR)")}</h1>

        {/* Phase 1 — transfers */}
        <h2 style={styles.h2}>{t("Phase 1 — Élimination des transferts", "Phase 1 — Transfer elimination", "Fase 1 — Eliminación de las transferencias")}</h2>
        {mprTransfers && mprTransfers.length > 0 ? (
          <table style={styles.table}>
            <thead><tr>
              <th style={styles.th}>{t("Libellé", "Label", "Denominación")}</th>
              <th style={styles.th}>{t("Catégorie", "Category", "Categoría")}</th>
              <th style={{ ...styles.th, ...styles.numTd }}>{t("Montant/an", "Amount/yr", "Importe/año")}</th>
            </tr></thead>
            <tbody>
              {mprTransfers.map((t) => (
                <tr key={t.id}>
                  <td style={styles.td}>{t.label}</td>
                  <td style={styles.td}>{xL("mprCat", t.category)}</td>
                  <td style={{ ...styles.td, ...styles.numTd }}>{fmtNum(t.amount_per_year)}</td>
                </tr>
              ))}
            </tbody>
          </table>
        ) : <p style={styles.p}>{t("(les intérêts de la dette sont déduits automatiquement)", "(debt interest deducted automatically)", "(los intereses de la deuda se deducen automáticamente)")}</p>}

        {/* Phase 2 — externalities */}
        <h2 style={styles.h2}>{t("Phase 2 — Externalités", "Phase 2 — Externalities", "Fase 2 — Externalidades")}</h2>
        {externalities && externalities.length > 0 ? (
          <table style={styles.table}>
            <thead><tr>
              <th style={styles.th}>{t("Libellé", "Label", "Denominación")}</th>
              <th style={styles.th}>{t("Nature", "Kind", "Naturaleza")}</th>
              <th style={styles.th}>{t("Catégorie", "Category", "Categoría")}</th>
              <th style={{ ...styles.th, ...styles.numTd }}>{t("Montant An 1", "Year 1 amount", "Monto Año 1")}</th>
            </tr></thead>
            <tbody>
              {externalities.map((e) => (
                <tr key={e.id}>
                  <td style={styles.td}>{e.label}</td>
                  <td style={styles.td}>{xL("extKind", e.kind)}</td>
                  <td style={styles.td}>{xL("extCat", e.category)}</td>
                  <td style={{ ...styles.td, ...styles.numTd, color: e.kind === "negative" ? "#dc2626" : "#16a34a" }}>{e.kind === "negative" ? "−" : "+"}{fmtNum(e.amount_year1)}</td>
                </tr>
              ))}
            </tbody>
          </table>
        ) : <p style={styles.p}>{t("(aucune externalité saisie)", "(no externality)", "(ninguna externalidad registrada)")}</p>}

        {/* Economic indicators */}
        {mprResult && (() => {
          const e = mprResult.indicators;
          const discEco = (inputs && inputs.discount_rate_economic) || 0.09;
          return (
            <>
              <h2 style={styles.h2}>{t("Indicateurs économiques", "Economic indicators", "Indicadores económicos")}</h2>
              <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 8, marginBottom: 12 }}>
                <KpiTile label="ENPV"                        value={fmtCurrency(e.enpv, ccy)}      status={tileColor(e.enpv, 0, ">")}     sub="≥ 0" />
                <KpiTile label="EIRR"                        value={fmtPct(e.eirr)}                 status={tileColor(e.eirr, discEco, ">")} sub={"> " + fmtPct(discEco)} />
                <KpiTile label={t("Ratio B/C", "B/C ratio", "Ratio B/C")} value={fmtRatio(e.bcRatio)}            status={tileColor(e.bcRatio, 1, ">")}    sub="≥ 1" />
                <KpiTile label={t("NPV bénéfices", "NPV benefits", "VAN beneficios")} value={fmtCurrency(e.npvBenefits, ccy)} status="neutral" sub={t("Actualisé", "Discounted", "Actualizado")} />
                <KpiTile label={t("NPV coûts", "NPV costs", "VAN costos")}         value={fmtCurrency(e.npvCosts, ccy)}    status="neutral" sub={t("Actualisé", "Discounted", "Actualizado")} />
              </div>
            </>
          );
        })()}

        {/* Donut chart of positive externalities by category */}
        {chartImages.donut && (
          <div style={{ marginTop: 14 }}>
            <img src={chartImages.donut} alt="Stakeholder donut" style={{ width: "100%", maxWidth: 460, display: "block", margin: "0 auto" }} />
          </div>
        )}

        {/* MPR Phase 3 — Conversion factors (Phase 7.2) */}
        {conversionFactors && conversionFactors.length > 0 && (
          <>
            <h2 style={styles.h2}>{t("Phase 3 — Facteurs de conversion", "Phase 3 — Conversion factors", "Fase 3 — Factores de conversión")}</h2>
            <p style={styles.p}>
              {t("Coefficients de prix fictifs appliqués automatiquement par le moteur dans le calcul de l'ENPV/EIRR/B/C (1.0 = prix de marché).",
                 "Shadow-price coefficients automatically applied to the ENPV/EIRR/B/C computation (1.0 = market price).", "Coeficientes de precios ficticios aplicados automáticamente por el motor en el cálculo de la VANE/TIRE/B/C (1.0 = precio de mercado).")}
            </p>
            <table style={styles.table}>
              <thead><tr>
                <th style={styles.th}>{t("Input", "Input", "Insumo")}</th>
                <th style={{ ...styles.th, ...styles.numTd }}>{t("Facteur", "Factor", "Factor")}</th>
                <th style={{ ...styles.th, ...styles.numTd }}>{t("Δ vs 1.0", "Δ vs 1.0", "Δ vs 1.0")}</th>
                <th style={styles.th}>{t("Justification", "Justification", "Justificación")}</th>
              </tr></thead>
              <tbody>
                {conversionFactors.map((f) => {
                  const labels = {
                    capex_local: t("CAPEX local", "Local CAPEX", "CAPEX local"),
                    capex_imported: t("CAPEX importé", "Imported CAPEX", "CAPEX importado"),
                    opex_personnel: t("OPEX — Personnel", "OPEX — Personnel", "OPEX — Personal"),
                    opex_materials: t("OPEX — Matières", "OPEX — Materials", "OPEX — Materias"),
                    revenue: t("Revenus", "Revenue", "Ingresos"),
                    other: t("Autres", "Other", "Otros"),
                  };
                  const val = Number(f.factor) || 1;
                  const delta = (val - 1) * 100;
                  return (
                    <tr key={f.id}>
                      <td style={styles.td}>{labels[f.input_kind] || f.input_kind}</td>
                      <td style={{ ...styles.td, ...styles.numTd, fontWeight: 700,
                        color: Math.abs(val - 1) < 0.02 ? "#374151" : val < 1 ? "#a16207" : "#15803d" }}>
                        {val.toFixed(2)}
                      </td>
                      <td style={{ ...styles.td, ...styles.numTd, color: "#6b7280" }}>
                        {(delta >= 0 ? "+" : "") + delta.toFixed(1) + "%"}
                      </td>
                      <td style={styles.td}>{f.notes || "—"}</td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </>
        )}

        {/* ===== VI. QUALITY & MULTI-CRITERIA ===== */}
        <div style={styles.pageBreak}></div>
        <h1 style={styles.h1}>{t("VI. Contrôle qualité & multicritère", "VI. Quality grid & multi-criteria", "VI. Control de calidad y multicriterio")}</h1>

        {qualityResult && (
          <>
            <h2 style={styles.h2}>
              {t("Grille de contrôle qualité (Tableau 9)", "Quality grid (Table 9)", "Cuadrícula de control de calidad (Tabla 9)")}
              <DecisionPill decision={qualityResult.decision} lang={lang} />
            </h2>
            <p style={styles.p}>
              <b>{t("Score global : ", "Global score: ", "Puntuación global: ")}</b>
              <span style={{ color: tileColor(qualityResult.pct, 0.6, ">") === "ok" ? "#15803d" : "#b91c1c", fontWeight: 700 }}>
                {fmtPct(qualityResult.pct)}
              </span>
              {" · "}
              <span className="text-faint">{qualityResult.scoredItems}/{qualityResult.totalItems} {t("critères évalués", "criteria scored", "criterios evaluados")}</span>
            </p>
            <table style={styles.table}>
              <thead><tr>
                <th style={styles.th}>{t("Dimension", "Dimension", "Dimensión")}</th>
                <th style={{ ...styles.th, ...styles.numTd }}>{t("Moyenne", "Average", "Promedio")}</th>
                <th style={{ ...styles.th, ...styles.numTd }}>%</th>
              </tr></thead>
              <tbody>
                {Object.entries(qualityResult.byDim).map(([dim, v]) => {
                  const status = v.pct >= 0.75 ? "ok" : v.pct >= 0.6 ? "amber" : "bad";
                  const c = COLORS[status];
                  return (
                    <tr key={dim}>
                      <td style={styles.td}>{dim}</td>
                      <td style={{ ...styles.td, ...styles.numTd }}>{v.avg.toFixed(2)}/3</td>
                      <td style={{ ...styles.td, ...styles.numTd, color: c.fg, background: c.bg, fontWeight: 700 }}>{fmtPct(v.pct)}</td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </>
        )}

        {mcResult && (
          <>
            <h2 style={styles.h2}>
              {t("Analyse multicritère (Tableau 21)", "Multi-criteria analysis (Table 21)", "Análisis multicriterio (Tabla 21)")}
              <DecisionPill decision={mcResult.decision} lang={lang} />
            </h2>
            <p style={styles.p}>
              <b>{t("Score pondéré global : ", "Weighted global score: ", "Puntuación ponderada global: ")}</b>
              <span style={{ color: tileColor(mcResult.globalPct, 0.75, ">") === "ok" ? "#15803d" : mcResult.globalPct >= 0.6 ? "#a16207" : "#b91c1c", fontWeight: 700 }}>
                {fmtPct(mcResult.globalPct)}
              </span>
              {" · "}
              <span className="text-faint">{mcResult.scoredItems}/{mcResult.totalItems} {t("sous-critères évalués", "sub-criteria scored", "subcriterios evaluados")}</span>
            </p>
            <table style={styles.table}>
              <thead><tr>
                <th style={styles.th}>{t("Dimension", "Dimension", "Dimensión")}</th>
                <th style={{ ...styles.th, ...styles.numTd }}>{t("Moy. pondérée", "Weighted avg", "Prom. ponderado")}</th>
                <th style={{ ...styles.th, ...styles.numTd }}>%</th>
              </tr></thead>
              <tbody>
                {Object.entries(mcResult.byDim).map(([dim, v]) => {
                  const status = v.pct >= 0.75 ? "ok" : v.pct >= 0.6 ? "amber" : "bad";
                  const c = COLORS[status];
                  return (
                    <tr key={dim}>
                      <td style={styles.td}>{dim}</td>
                      <td style={{ ...styles.td, ...styles.numTd }}>{v.weightedAvg.toFixed(2)}/3</td>
                      <td style={{ ...styles.td, ...styles.numTd, color: c.fg, background: c.bg, fontWeight: 700 }}>{fmtPct(v.pct)}</td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </>
        )}

        {/* ===== Environnement, Social & Genre — placé AVANT l'institutionnel ===== */}
        {(() => {
          const x = institutional || {};
          const es = [["env_social_category","Catégorie E&S","E&S category"],["eies_status","Statut EIES / NIES","EIA / IEE status"],["env_impacts","Impacts environnementaux","Environmental impacts"],["env_mitigation","Atténuation (PGES)","Mitigation (ESMP)"],["climate_resilience","Résilience climatique","Climate resilience"],["social_impacts","Impacts sociaux","Social impacts"],["resettlement_plan","Réinstallation / foncier","Resettlement / land"],["grievance_mechanism","Mécanisme de plaintes","Grievance mechanism"],["vulnerable_groups","Groupes vulnérables","Vulnerable groups"]];
          const gd = [["gender_analysis","Diagnostic genre","Gender analysis"],["gender_measures","Mesures sensibles au genre","Gender-responsive measures"],["gender_targets","Cibles / indicateurs genre","Gender targets / indicators"]];
          if (!es.concat(gd).some(([k]) => x[k] && String(x[k]).trim())) return null;
          const KV = ({ label, value }) => value ? (
            <div style={styles.kv}><span style={styles.kvLabel}>{label}</span><span>{value}</span></div>
          ) : null;
          return (
            <>
              <h1 style={styles.h1}>{t("VII. Environnement, Social & Genre", "VII. Environmental, Social & Gender", "VII. Medio ambiente, Social y Género")}</h1>
              <h2 style={styles.h2}>{t("Sauvegardes environnementales & sociales", "Environmental & social safeguards", "Salvaguardias ambientales y sociales")}</h2>
              {es.map(([k, fr, en]) => <KV key={k} label={t(fr, en)} value={x[k]} />)}
              <h2 style={styles.h2}>{t("Analyse genre", "Gender analysis", "Análisis de género")}</h2>
              {gd.map(([k, fr, en]) => <KV key={k} label={t(fr, en)} value={x[k]} />)}
            </>
          );
        })()}

        {/* ===== VII bis. Institutional analysis (Section X of the guide) ===== */}
        {institutional && (institutional.legal_framework || institutional.management_model || institutional.carrier_organizations || institutional.sustainability_mechanisms) && (() => {
          const inst = institutional;
          const block = (title, fields) => (
            <div style={{ marginBottom: 12 }}>
              <h3 style={styles.h3}>{title}</h3>
              {fields.filter(([_, v]) => v && String(v).trim()).map(([label, v]) => (
                <div key={label} style={{ marginBottom: 6 }}>
                  <div style={{ ...styles.kvLabel }}>{label}</div>
                  <div style={{ fontSize: 11, lineHeight: 1.5 }}>{v}</div>
                </div>
              ))}
            </div>
          );
          const mgmtModelLabels = {
            regie: t("Régie publique directe", "Direct public management", "Gestión pública directa"),
            concession: t("Concession", "Concession", "Concesión"),
            ppp: t("Partenariat Public-Privé", "Public-Private Partnership", "Asociación Público-Privada"),
            delegation: t("Délégation de service public", "Public service delegation", "Delegación de servicio público"),
            community: t("Gestion communautaire", "Community-based", "Gestión comunitaria"),
            mixed: t("Modèle mixte", "Mixed model", "Modelo mixto"),
            other: t("Autre", "Other", "Otro"),
          };
          return (
            <>
              <div style={styles.pageBreak}></div>
              <h1 style={styles.h1}>{t("VII bis. Analyse institutionnelle", "VII bis. Institutional analysis", "VII bis. Análisis institucional")}</h1>
              {block(t("1. Cadre juridique & réglementaire", "1. Legal & regulatory framework", "1. Marco jurídico y reglamentario"), [
                [t("Cadre légal applicable", "Applicable legal framework", "Marco legal aplicable"), inst.legal_framework],
                [t("Contraintes / autorisations", "Constraints / permits", "Restricciones / autorizaciones"), inst.juridical_constraints],
                [t("Normes techniques applicables", "Applicable technical norms", "Normas técnicas aplicables"), inst.applicable_norms],
              ])}
              {block(t("2. Modèle de gestion", "2. Management model", "2. Modelo de gestión"), [
                [t("Modèle retenu", "Selected model", "Modelo seleccionado"), mgmtModelLabels[inst.management_model] || inst.management_model],
                [t("Détails du modèle", "Model details", "Detalles del modelo"), inst.management_model_details],
                [t("Opérateur identifié", "Identified operator", "Operador identificado"), inst.operator_identification],
                [t("Arrangements contractuels", "Contractual arrangements", "Acuerdos contractuales"), inst.contractual_arrangements],
              ])}
              {block(t("3. Capacités institutionnelles des porteurs", "3. Carrier institutional capacities", "3. Capacidades institucionales de las entidades responsables"), [
                [t("Organisations porteuses", "Carrier organisations", "Organizaciones responsables"), inst.carrier_organizations],
                [t("Capacités actuelles", "Existing capacities", "Capacidades actuales"), inst.existing_capacities],
                [t("Écarts identifiés", "Capacity gaps", "Brechas identificadas"), inst.capacity_gaps],
                [t("Plan de renforcement", "Capacity-building plan", "Plan de fortalecimiento"), inst.capacity_building_plan],
              ])}
              {block(t("4. Coordination & gouvernance", "4. Coordination & governance", "4. Coordinación y gobernanza"), [
                [t("Mécanismes de coordination", "Coordination mechanisms", "Mecanismos de coordinación"), inst.coordination_mechanisms],
                [t("Instances de décision", "Decision-making bodies", "Instancias de decisión"), inst.decision_making_bodies],
                [t("Dispositif institutionnel de S&E", "Institutional M&E arrangements", "Disposiciones institucionales de SyE"), inst.monitoring_arrangements],
              ])}
              {block(t("5. Durabilité institutionnelle", "5. Institutional sustainability", "5. Sostenibilidad institucional"), [
                [t("Mécanismes de durabilité", "Sustainability mechanisms", "Mecanismos de sostenibilidad"), inst.sustainability_mechanisms],
                [t("Transfert de propriété post-projet", "Post-project ownership transfer", "Transferencia de propiedad posproyecto"), inst.ownership_transfer],
                [t("Ressources O&M futures", "Future O&M resources", "Recursos de O&M futuros"), inst.post_project_resources],
              ])}
              {(inst.institutional_risks || inst.risk_mitigation_measures) && block(
                t("6. Risques institutionnels", "6. Institutional risks", "6. Riesgos institucionales"),
                [
                  [t("Risques identifiés", "Identified risks", "Riesgos identificados"), inst.institutional_risks],
                  [t("Mesures de mitigation", "Mitigation measures", "Medidas de mitigación"), inst.risk_mitigation_measures],
                ]
              )}
            </>
          );
        })()}

        {/* ===== VII. Sensitivity heatmap ===== */}
        {exanteComputed && mprResult && window.exanteEngine && (() => {
          const E = window.exanteEngine;
          const baseOpts = {
            inputs, scen,
            capexLines: capexLines || [], opexLines: opexLines || [],
            revenueLines: revenueLines || [], financingSources: finSources || [],
          };
          const mprBaseOpts = {
            inputs, capexLines: capexLines || [],
            opexByYear: exanteComputed.opexByYear,
            revenueByYear: exanteComputed.revenueByYear,
            debtSchedule: exanteComputed.debt,
            mprTransfers: mprTransfers || [],
            externalities: externalities || [],
            conversionFactors: null,
          };
          const vars = [
            { v: "capex",    fr: "CAPEX",                en: "CAPEX", es: "CAPEX" },
            { v: "volumes",  fr: "Volumes",              en: "Volumes", es: "Volúmenes" },
            { v: "tariffs",  fr: "Tarifs",               en: "Tariffs", es: "Tarifas" },
            { v: "opex",     fr: "OPEX",                 en: "OPEX", es: "OPEX" },
            { v: "discount", fr: "Taux d'actualisation", en: "Discount rate", es: "Tasa de descuento" },
          ];
          const deltas = [-0.20, -0.10, 0, 0.10, 0.20];
          let matrix;
          try {
            matrix = vars.map((v) => ({
              v,
              cells: deltas.map((d) => E.economicSensitivityShock(baseOpts, mprBaseOpts, v.v, d)),
            }));
          } catch (e) {
            return null;
          }
          // Display VAN (financial NPV) as default metric
          return (
            <>
              <h1 style={styles.h1}>{t("VIII. Analyse de sensibilité (VAN projet)", "VIII. Sensitivity analysis (Project NPV)", "VIII. Análisis de sensibilidad (VAN del proyecto)")}</h1>
              <p style={styles.p}>
                {t("Heatmap de la VAN projet pour 5 variables × 5 chocs (−20% à +20%). Vert = ≥ 0 (viable), rouge = < 0.",
                   "Project NPV heatmap for 5 variables × 5 shocks (−20% to +20%). Green = ≥ 0 (viable), red = < 0.", "Mapa de calor de la VAN del proyecto para 5 variables × 5 choques (−20% a +20%). Verde = ≥ 0 (viable), rojo = < 0.")}
              </p>
              <table style={styles.table}>
                <thead><tr>
                  <th style={styles.th}>{t("Variable", "Variable", "Variable")}</th>
                  {deltas.map((d) => <th key={d} style={{ ...styles.th, ...styles.numTd }}>{d === 0 ? "Base" : (d > 0 ? "+" : "") + Math.round(d * 100) + "%"}</th>)}
                </tr></thead>
                <tbody>
                  {matrix.map((row) => (
                    <tr key={row.v.v}>
                      <td style={{ ...styles.td, fontWeight: 600 }}>{t(row.v.fr, row.v.en)}</td>
                      {row.cells.map((res, i) => {
                        const value = res.fin && res.fin.npvProject;
                        return (
                          <td key={i} style={{
                            ...styles.td, ...styles.numTd,
                            background: heatmapColor(value, 0, ">"),
                            fontWeight: i === 2 ? 700 : 500,
                          }}>
                            {fmtNum(value)}
                          </td>
                        );
                      })}
                    </tr>
                  ))}
                </tbody>
              </table>
              <p style={{ ...styles.p, fontSize: 10, color: "#6b7280" }}>
                {t("Les seuils des autres indicateurs (TRI > taux actu., DSCR ≥ 1,2, ENPV ≥ 0, etc.) sont disponibles dans l'app via les sélecteurs de métrique.",
                   "Other indicator thresholds available in the live app via the metric selector.", "Los umbrales de los demás indicadores (TIR > tasa de actual., DSCR ≥ 1,2, VANE ≥ 0, etc.) están disponibles en la app mediante los selectores de métrica.")}
              </p>
              {chartImages.sensitivity && (
                <div style={{ marginTop: 14 }}>
                  <img src={chartImages.sensitivity} alt="Sensitivity heatmap" style={{ width: "100%", maxWidth: 600, display: "block", margin: "0 auto" }} />
                </div>
              )}
            </>
          );
        })()}

        {/* ===== VIII (suite). Scénarios multicritères + Tornado ===== */}
        {(() => {
          const synth = (typeof window !== "undefined" && window.EXANTE_REPORT_SYNTH) || null;
          // Valeurs réelles du payload en priorité ; repli sur la synthèse illustrative.
          const scenarios = (reportScenarios && reportScenarios.length) ? reportScenarios : (synth && synth.scenarios ? synth.scenarios(lang) : []);
          const tornado = (reportTornado && reportTornado.length) ? reportTornado : (synth && synth.tornado ? synth.tornado(lang) : []);
          const unit = reportTornadoUnit || "M€";
          if (!scenarios.length && !tornado.length) return null;
          const pill = (k) => k === "ok" ? { bg: "#dcfce7", fg: "#15803d", txt: t("Acceptable", "Acceptable", "Aceptable") }
                            : k === "warn" ? { bg: "#fef3c7", fg: "#b45309", txt: t("Attention", "Caution", "Atención") }
                            : { bg: "#fee2e2", fg: "#b91c1c", txt: t("Non viable", "Not viable", "No viable") };
          // Tornado SVG — graduations « rondes » adaptatives (toute échelle).
          let range = 1;
          tornado.forEach((d) => { range = Math.max(range, Math.abs(d.neg), Math.abs(d.pos)); });
          const niceStep = (r) => { const raw = r / 4, mag = Math.pow(10, Math.floor(Math.log10(raw))), n = raw / mag; return (n < 1.5 ? 1 : n < 3 ? 2 : n < 7 ? 5 : 10) * mag; };
          const step = niceStep(range) || 1;
          const rangeCeil = Math.ceil(range / step) * step;
          const fmtN = (v) => (Math.abs(v) >= 1000 ? Math.round(v).toLocaleString(window.melrLocale(window.__melrLang)) : String(Math.round(v * 10) / 10));
          const TW = 560, padL = 160, padR = 50, padT = 26, rowH = 30;
          const TH = tornado.length * rowH + padT + 16;
          const cxx = padL + (TW - padL - padR) / 2;
          const sc = (TW - padL - padR) / 2 / rangeCeil;
          const grads = [];
          for (let g = -rangeCeil; g <= rangeCeil + 1e-9; g += step) grads.push(Math.round(g * 1000) / 1000);
          return (
            <>
              {scenarios.length > 0 && (
                <>
                  <h2 style={styles.h2}>{t("Scénarios multicritères", "Multi-criteria scenarios", "Escenarios multicriterio")}</h2>
                  <table style={styles.table}>
                    <thead><tr>
                      <th style={styles.th}>{t("Scénario", "Scenario", "Escenario")}</th>
                      <th style={{ ...styles.th, ...styles.numTd }}>VAN</th>
                      <th style={{ ...styles.th, ...styles.numTd }}>TRI</th>
                      <th style={{ ...styles.th, ...styles.numTd }}>DSCR</th>
                      <th style={styles.th}>{t("Verdict", "Verdict", "Veredicto")}</th>
                    </tr></thead>
                    <tbody>
                      {scenarios.map((r, i) => {
                        const p = pill(r.k);
                        return (
                          <tr key={i}>
                            <td style={{ ...styles.td, fontWeight: 600 }}>{r.s}</td>
                            <td style={{ ...styles.td, ...styles.numTd }}>{r.v}</td>
                            <td style={{ ...styles.td, ...styles.numTd }}>{r.t}</td>
                            <td style={{ ...styles.td, ...styles.numTd }}>{r.d}</td>
                            <td style={styles.td}>
                              <span style={{ background: p.bg, color: p.fg, padding: "2px 8px", borderRadius: 999, fontSize: 10, fontWeight: 600 }}>{p.txt}</span>
                            </td>
                          </tr>
                        );
                      })}
                    </tbody>
                  </table>
                </>
              )}
              {tornado.length > 0 && (
                <>
                  <h2 style={styles.h2}>{t("Tornado · sensibilité VAN", "Tornado · NPV sensitivity", "Tornado · sensibilidad VAN")} ({unit})</h2>
                  <svg viewBox={`0 0 ${TW} ${TH}`} style={{ width: "100%", maxWidth: 640, display: "block", margin: "0 auto 12px" }}>
                    <line x1={cxx} x2={cxx} y1={padT - 4} y2={TH - 8} stroke="#334155" />
                    {grads.map((g, gi) => (
                      <g key={gi}>
                        <line x1={cxx + g * sc} x2={cxx + g * sc} y1={padT - 2} y2={TH - 8} stroke="#e8edf3" />
                        <text x={cxx + g * sc} y={padT - 6} fontSize="9" textAnchor="middle" fill="#94a3b8">{g > 0 ? "+" : ""}{fmtN(g)}</text>
                      </g>
                    ))}
                    {tornado.map((d, i) => {
                      const y = padT + i * rowH;
                      return (
                        <g key={i}>
                          <text x={padL - 8} y={y + rowH / 2 + 3} fontSize="9.5" textAnchor="end" fill="#111827">{d.n}</text>
                          <rect x={cxx + d.neg * sc} y={y + 5} width={-d.neg * sc} height={rowH - 12} fill="#dc2626" opacity="0.72" />
                          <rect x={cxx} y={y + 5} width={d.pos * sc} height={rowH - 12} fill="#15803d" opacity="0.72" />
                          {d.neg < 0 && <text x={cxx + d.neg * sc - 3} y={y + rowH / 2 + 3} fontSize="9" textAnchor="end" fill="#64748b">{fmtN(d.neg)}</text>}
                          {d.pos > 0 && <text x={cxx + d.pos * sc + 3} y={y + rowH / 2 + 3} fontSize="9" fill="#64748b">+{fmtN(d.pos)}</text>}
                        </g>
                      );
                    })}
                  </svg>
                </>
              )}
            </>
          );
        })()}

        {/* ===== IX. Recommandations, conditions & risques résiduels ===== */}
        {(() => {
          const synth = (typeof window !== "undefined" && window.EXANTE_REPORT_SYNTH) || null;
          // Avis réel (texte calculé) en priorité ; repli sur la synthèse illustrative.
          const reco = reportReco || (synth && synth.reco ? synth.reco(lang) : null);
          const split = (txt) => String(txt || "").split(/\r?\n|;|•/).map((s) => s.trim()).filter((s) => s.length > 1);
          let conditions = split(ident && ident.preconditions).concat(split(institutional && institutional.sustainability_mechanisms));
          let residual = split(ident && ident.main_risks).concat(split(institutional && institutional.institutional_risks));
          const usingRecoRisks = !residual.length && reco && reco.risks && reco.risks.length;
          if (!conditions.length && reco) conditions = reco.conditions.slice();
          if (!conditions.length && !residual.length && !usingRecoRisks && !reco) return null;
          return (
            <>
              <h1 style={styles.h1}>{t("IX. Recommandations, conditions & risques résiduels", "IX. Recommendations, conditions & residual risks", "IX. Recomendaciones, condiciones y riesgos residuales")}</h1>
              {reco && reco.text && (
                <div style={{ background: "#f0fdf4", border: "1px solid #86efac", borderRadius: 8, padding: 14, marginBottom: 14 }}>
                  <div style={{ fontWeight: 700, color: "#15803d", marginBottom: 6, fontSize: 12 }}>✓ {reco.title}</div>
                  <div style={{ fontSize: 11, lineHeight: 1.5, color: "#374151" }}>{reco.text}</div>
                </div>
              )}
              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
                <div>
                  <h2 style={styles.h2}>{t("Conditions de mise en œuvre", "Implementation conditions", "Condiciones de implementación")}</h2>
                  <ul style={{ margin: 0, paddingLeft: 18, fontSize: 11, lineHeight: 1.6 }}>
                    {conditions.map((c, i) => <li key={i}>{c}</li>)}
                  </ul>
                </div>
                <div>
                  <h2 style={styles.h2}>{t("Risques résiduels à suivre", "Residual risks to monitor", "Riesgos residuales a seguir")}</h2>
                  {residual.length > 0 ? (
                    <ul style={{ margin: 0, paddingLeft: 18, fontSize: 11, lineHeight: 1.6 }}>
                      {residual.map((r, i) => <li key={i}>{r}</li>)}
                    </ul>
                  ) : usingRecoRisks ? (
                    <table style={styles.table}>
                      <thead><tr>
                        <th style={styles.th}>{t("Risque", "Risk", "Riesgo")}</th>
                        <th style={styles.th}>P</th>
                        <th style={styles.th}>I</th>
                      </tr></thead>
                      <tbody>
                        {reco.risks.map((r, i) => (
                          <tr key={i}>
                            <td style={styles.td}>{r.r}</td>
                            <td style={styles.td}><span style={{ background: "#fef3c7", color: "#b45309", padding: "1px 6px", borderRadius: 999, fontSize: 10 }}>{r.p}</span></td>
                            <td style={styles.td}><span style={{ background: "#fee2e2", color: "#b91c1c", padding: "1px 6px", borderRadius: 999, fontSize: 10 }}>{r.i}</span></td>
                          </tr>
                        ))}
                      </tbody>
                    </table>
                  ) : null}
                </div>
              </div>
            </>
          );
        })()}

        {/* ===== FOOTER ===== */}
        <div style={{ marginTop: 40, paddingTop: 16, borderTop: "1px solid #e5e7eb", fontSize: 10, color: "#6b7280", textAlign: "center" }}>
          {t("Document généré automatiquement par MELR — ", "Generated automatically by MELR — ", "Documento generado automáticamente por MELR — ")}{today}
          <br />
          {t("Document de référence — Évaluation ex ante", "Reference document — Ex-ante appraisal", "Documento de referencia — Evaluación ex ante")}
        </div>
      </div>
    );
  }

  // ------------------------------------------------------------------------
  // Modal wrapper with print and Word-export buttons
  // ------------------------------------------------------------------------
  function ExanteReportModal(props) {
    const onPrint = () => window.print();
    const onExportDoc = () => {
      // Build a minimal HTML envelope so Word can open it cleanly.
      const reportNode = document.getElementById("exante-report-printable");
      if (!reportNode) return;
      const html = `<!DOCTYPE html>
<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta charset="utf-8">
<title>Évaluation ex-ante</title>
<style>
  body { font-family: Calibri, sans-serif; font-size: 11pt; }
  h1 { font-size: 18pt; color: #1f2937; border-bottom: 2px solid #1f2937; padding-bottom: 4pt; }
  h2 { font-size: 14pt; color: #374151; }
  h3 { font-size: 12pt; color: #4b5563; }
  table { border-collapse: collapse; width: 100%; margin-bottom: 12pt; }
  th { background: #f9fafb; border-bottom: 2px solid #1f2937; padding: 4pt 6pt; text-align: left; font-weight: bold; }
  td { border-bottom: 1px solid #e5e7eb; padding: 4pt 6pt; vertical-align: top; }
</style>
</head>
<body>
${reportNode.innerHTML}
</body></html>`;
      const blob = new Blob(["﻿", html], { type: "application/msword" });
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      const code = (props.dossier && props.dossier.projects && props.dossier.projects.code) || "exante";
      const date = new Date().toISOString().slice(0, 10);
      a.href = url; a.download = `exante-${code}-${date}.doc`;
      document.body.appendChild(a); a.click(); document.body.removeChild(a);
      URL.revokeObjectURL(url);
    };

    return (
      <div className="exante-report-overlay" style={{
        position: "fixed", inset: 0, background: "rgba(0,0,0,.6)", zIndex: 9999,
        display: "flex", flexDirection: "column",
      }}>
        {/* Toolbar (hidden on print) */}
        <div className="exante-report-toolbar" style={{
          padding: "10px 16px", background: "var(--bg, white)", color: "var(--text, #111)",
          borderBottom: "1px solid var(--line)", display: "flex", gap: 10, alignItems: "center",
        }}>
          <div style={{ fontWeight: 600, fontSize: 14 }}>
            {props.lang === "es" ? "Informe de evaluación ex ante" : props.lang === "fr" ? "Rapport d'évaluation ex-ante" : "Ex-ante appraisal report"}
          </div>
          <div style={{ flex: 1 }} />
          {window.exportExanteDocxAvailable && (
            <button onClick={() => window.exportExanteDocx(props)}
              style={{ padding: "8px 14px", borderRadius: 6, border: "1px solid #2563eb", background: "#2563eb", color: "white", cursor: "pointer", fontWeight: 600, fontSize: 13 }}>
              📄 Word (.docx)
            </button>
          )}
          <button onClick={onExportDoc}
            style={{ padding: "8px 14px", borderRadius: 6, border: "1px solid #2563eb", background: "#2563eb", color: "white", cursor: "pointer", fontWeight: 600, fontSize: 13 }}
            title="Format Word HTML simple (compatibilité large)">
            📄 Word (.doc)
          </button>
          <button onClick={onPrint}
            style={{ padding: "8px 14px", borderRadius: 6, border: "1px solid #dc2626", background: "#dc2626", color: "white", cursor: "pointer", fontWeight: 600, fontSize: 13 }}>
            📕 {props.lang === "es" ? "Imprimir / PDF" : props.lang === "fr" ? "Imprimer / PDF" : "Print / PDF"}
          </button>
          <button onClick={props.onClose}
            style={{ padding: "8px 14px", borderRadius: 6, border: "1px solid var(--line)", background: "transparent", color: "var(--text)", cursor: "pointer" }}>
            {props.lang === "es" ? "Cerrar" : props.lang === "fr" ? "Fermer" : "Close"}
          </button>
        </div>
        {/* Printable area */}
        <div className="exante-report-scroll" style={{
          flex: 1, overflowY: "auto", background: "#e5e7eb", padding: 20,
        }}>
          <div id="exante-report-printable" style={{ background: "white", boxShadow: "0 4px 14px rgba(0,0,0,.15)" }}>
            <ExanteReport {...props} />
          </div>
        </div>
      </div>
    );
  }

  window.ExanteReport = ExanteReport;
  window.ExanteReportModal = ExanteReportModal;
})();
