/* global React, window */
// ============================================================================
// Chantier I · Page de tarification publique
// ----------------------------------------------------------------------------
// Route activée par `?pricing=1` ou `#pricing` ou `#/pricing` — accessible
// SANS authentification : les visiteurs depuis la landing reft-africa.org
// peuvent y arriver directement.
//
// Layout 3 colonnes (Free / Pro / Enterprise) avec :
//   - Sélecteur de devise (EUR / USD / XOF) — l'Afrique de l'Ouest est
//     un public majeur, le tarif XOF doit être présent.
//   - Bascule mensuel / annuel (annuel = -2 mois, soit ×10 au lieu de ×12).
//   - Features cochées par plan.
//   - CTA distinct par plan :
//       Free       → « Commencer gratuitement » → /MELR (signup)
//       Pro        → « S'abonner » → checkout Stripe
//       Enterprise → « Demander un devis » → mailto: it@reft-africa.org
//   - FAQ basique sous les colonnes.
//
// Pour un déploiement marketing pur (sans auth), la même structure de
// page pourrait être dupliquée en HTML statique sur reft-africa.org.
// Ici on garde la version "in-app" parce qu'elle pull les vrais prix
// depuis plan_definitions (single source of truth).
// ============================================================================

(function () {
  const { useState, useMemo } = React;

  function PricingPage({ lang: langProp, onClose }) {
    const [lang, setLang] = useState(langProp || "fr");
    const [currency, setCurrency] = useState("EUR");
    const [cycle, setCycle] = useState("monthly");  // monthly | yearly
    const { data: plans, loading } = window.melr.usePlanDefinitions(currency);

    // Format prix selon la devise. XOF n'a pas de centimes (les "cents"
    // côté DB sont déjà entiers en XOF par convention).
    const fmtPrice = (cents, ccy) => {
      if (cents == null || cents === 0) return null;
      const v = ccy === "XOF" ? cents : cents / 100;
      const opts = { style: "currency", currency: ccy, maximumFractionDigits: ccy === "XOF" ? 0 : 0 };
      try { return new Intl.NumberFormat(window.L("fr-FR", "en-US", "es-ES"), opts).format(v); }
      catch (_) { return v + " " + ccy; }
    };

    // Quand l'user clique « S'abonner » : on ouvre un modal qui propose
    // les moyens de paiement activés et compatibles avec le plan + devise.
    // Si un seul moyen est dispo, on saute directement à son action.
    const [methodPicker, setMethodPicker] = useState(null);  // { plan } | null
    const [methodModal, setMethodModal]   = useState(null);  // { method, plan } pour kind=manual

    const onSubscribe = (plan) => {
      if (plan.code === "free") {
        window.location.href = "/MELR?signup=1";
        return;
      }
      // Tous les plans payants passent par le picker (qui propose Stripe,
      // PayPal, Orange Money, Wave, virement…). Plus de hardcoding du flow.
      setMethodPicker({ plan });
    };

    // Action une fois un moyen de paiement choisi par l'utilisateur
    const onMethodChosen = async (method, plan) => {
      setMethodPicker(null);
      if (method.kind === "stripe") {
        const successUrl = window.location.origin + "/MELR?billing=success";
        const cancelUrl  = window.location.origin + "/MELR?pricing=1";
        const url = await window.melr.createStripeCheckoutSession({
          plan_code: plan.code, currency, billing_cycle: cycle,
          success_url: successUrl, cancel_url: cancelUrl,
        });
        if (url) window.location.href = url;
        else alert(window.L("Stripe n'est pas encore configuré sur cette instance. Choisissez un autre moyen de paiement ou écrivez à it@reft-africa.org.", "Stripe is not yet configured on this instance. Pick another payment method or email it@reft-africa.org.", "Stripe aún no está configurado en esta instancia. Elija otro método de pago o escriba a it@reft-africa.org."));
        return;
      }
      if (method.kind === "redirect" && method.redirect_url) {
        window.location.href = method.redirect_url
          .replace("{plan}", plan.code)
          .replace("{currency}", currency)
          .replace("{cycle}", cycle);
        return;
      }
      // kind === "manual" : on affiche les instructions dans un modal
      setMethodModal({ method, plan });
    };

    // Features réutilisables — affichées par check/cross selon plan.features
    const FEATURE_CATALOG = [
      { code: "core",                 fr: "Tous les modules MEAL de base",         en: "All core MEAL modules", es: "Todos los módulos MEAL básicos" },
      { code: "indicators_multi",     fr: "Indicateurs multi-frameworks (USAID, PEFA, WHO…)", en: "Multi-framework indicators", es: "Indicadores multimarco (USAID, PEFA, WHO…)" },
      { code: "evaluations_suite",    fr: "Suite Évaluations (PEFA, politiques publiques, impact & formations, mi-parcours & finale, diagnostics GFP)", en: "Evaluations suite (PEFA, public policy, impact & training, mid-term & final, PFM diagnostics)", es: "Suite de Evaluaciones (PEFA, políticas públicas, impacto y formación, intermedia y final, diagnósticos GFP)" },
      { code: "mobile",               fr: "Collecte mobile PWA + offline",         en: "PWA mobile collection + offline", es: "Recolección móvil PWA + sin conexión" },
      // ── Pro tier ──────────────────────────────────────────────────────
      { code: "exante",               fr: "Évaluation ex-ante par Prix de Référence", en: "Ex-ante appraisal by Reference Price", es: "Evaluación ex ante por Precio de Referencia" },
      { code: "dhis2",                fr: "Intégration DHIS2 (push / pull)",       en: "DHIS2 integration (push / pull)", es: "Integración DHIS2 (push / pull)" },
      { code: "msc",                  fr: "Module Histoires de changement (MSC)", en: "Stories of change module (MSC)", es: "Módulo Historias de cambio (MSC)" },
      { code: "learning",             fr: "Apprentissage (le L de MELR)",         en: "Learning (the L in MELR)", es: "Aprendizaje (la L de MELR)" },
      { code: "kobo_odk",             fr: "Intégration KoboToolbox / ODK Central", en: "KoboToolbox / ODK Central integration", es: "Integración KoboToolbox / ODK Central" },
      { code: "portfolio",            fr: "Tableau de bord portefeuille bailleur", en: "Donor portfolio dashboard", es: "Panel de cartera del donante" },
      { code: "logframe_export",      fr: "Cadre logique exportable (Word, donateur)", en: "Logframe export (Word, donor)", es: "Marco lógico exportable (Word, donante)" },
      { code: "donor_templates",      fr: "Templates bailleurs (USAID, GAVI, GF, AFD, UE, BM)", en: "Donor templates (USAID, GAVI, GF, AFD, EU, WB)", es: "Plantillas de donantes (USAID, GAVI, GF, AFD, UE, BM)" },
      // ── Enterprise tier ───────────────────────────────────────────────
      { code: "ai_assist",            fr: "Assistant IA (suggestion, résumé)",     en: "AI assistant (suggest, summarize)", es: "Asistente de IA (sugerencia, resumen)" },
      { code: "api",                  fr: "API publique REST",                     en: "Public REST API", es: "API pública REST" },
      { code: "white_label",          fr: "Marque blanche (logo, couleurs)",       en: "White-label (logo, colors)", es: "Marca blanca (logo, colores)" },
      { code: "dedicated_support",    fr: "Support dédié (chat + visio)",          en: "Dedicated support (chat + video)", es: "Soporte dedicado (chat + videollamada)" },
      { code: "sla",                  fr: "SLA contractualisé 99.9 %",             en: "Contractual 99.9 % SLA", es: "SLA contractual del 99,9 %" },
      { code: "backup_dr",            fr: "Backup quotidien + restore garanti",    en: "Daily backup + guaranteed restore", es: "Copia de seguridad diaria + restauración garantizada" },
    ];

    // Pour chaque plan, on calcule l'état de chaque feature : "in" (incluse),
    // "out" (hors plan), "core" (toujours dispo - tous les plans).
    const hasFeatureIn = (plan, code) => {
      // 'core', 'indicators_multi', 'evaluations_suite', 'mobile', 'donor_templates' : tous les plans
      if (["core","indicators_multi","evaluations_suite","mobile","donor_templates"].indexOf(code) >= 0) return true;
      const f = plan.features || [];
      return Array.isArray(f) && f.indexOf(code) >= 0;
    };

    const containerStyle = {
      minHeight: "100vh", background: "linear-gradient(180deg, #f8fafc 0%, #ffffff 100%)",
      padding: "28px 20px 80px", color: "#0f172a",
      fontFamily: "system-ui, -apple-system, 'Segoe UI', Helvetica, Arial, sans-serif",
    };
    const containerInner = { maxWidth: 1200, margin: "0 auto" };
    const colCount = (plans || []).length || 3;

    return (
      <div style={containerStyle}>
        <div style={containerInner}>
          {/* Header — branding + lang/currency switcher */}
          <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 16, marginBottom: 32, flexWrap: "wrap" }}>
            <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
              <a href="/MELR" style={{ fontSize: 22, fontWeight: 800, color: "#0f766e", textDecoration: "none" }}>
                <span style={{ marginRight: 6 }}>📊</span>MELR
              </a>
              <span style={{ color: "#64748b", fontSize: 14 }}>· {window.L("Tarifs", "Pricing", "Tarifas")}</span>
            </div>
            <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
              <select value={currency} onChange={(e) => setCurrency(e.target.value)}
                style={{ padding: "6px 10px", borderRadius: 6, border: "1px solid #cbd5e1", background: "white", fontSize: 13, cursor: "pointer" }}>
                <option value="EUR">€ EUR</option>
                <option value="USD">$ USD</option>
                <option value="XOF">CFA XOF</option>
              </select>
              <div style={{ display: "inline-flex", border: "1px solid #cbd5e1", borderRadius: 6, overflow: "hidden" }}>
                <button onClick={() => setLang("fr")}
                  style={{ padding: "6px 10px", border: "none", background: window.L("#0f766e", "white", "#0f766e"), color: window.L("white", "#0f172a", "white"), cursor: "pointer", fontSize: 13, fontWeight: 600 }}>FR</button>
                <button onClick={() => setLang("en")}
                  style={{ padding: "6px 10px", border: "none", background: lang === "en" ? "#0f766e" : "white", color: lang === "en" ? "white" : "#0f172a", cursor: "pointer", fontSize: 13, fontWeight: 600 }}>EN</button>
              </div>
              <a href="/MELR" style={{ padding: "6px 14px", borderRadius: 6, background: "white", border: "1px solid #cbd5e1", color: "#0f172a", textDecoration: "none", fontSize: 13, fontWeight: 600 }}>
                {window.L("Accéder à l'application →", "Open the app →", "Acceder a la aplicación →")}
              </a>
            </div>
          </div>

          {/* Title */}
          <div style={{ textAlign: "center", marginBottom: 36 }}>
            <h1 style={{ fontSize: 40, fontWeight: 800, margin: "0 0 12px", letterSpacing: "-0.02em" }}>
              {window.L("Choisissez le plan adapté à votre organisation", "Choose the plan that fits your organization", "Elija el plan adecuado para su organización")}
            </h1>
            <p style={{ fontSize: 17, color: "#475569", maxWidth: 720, margin: "0 auto", lineHeight: 1.55 }}>
              {window.L("Plateforme MEAL complète : indicateurs, activités, baseline, ex-ante, reporting, intégration DHIS2, exports bailleurs. Démarrez gratuitement, sans carte bancaire.", "Complete MEAL platform: indicators, activities, baseline, ex-ante, reporting, DHIS2 integration, donor exports. Start for free, no credit card required.", "Plataforma MEAL completa: indicadores, actividades, línea de base, ex-ante, generación de informes, integración DHIS2, exportaciones para donantes. Empiece gratis, sin tarjeta bancaria.")}
            </p>

            {/* Cycle toggle */}
            <div style={{ display: "inline-flex", marginTop: 20, padding: 4, background: "#e2e8f0", borderRadius: 999 }}>
              <button onClick={() => setCycle("monthly")}
                style={{ padding: "8px 18px", border: "none", borderRadius: 999, background: cycle === "monthly" ? "white" : "transparent", color: cycle === "monthly" ? "#0f172a" : "#64748b", fontWeight: 600, cursor: "pointer", fontSize: 13, boxShadow: cycle === "monthly" ? "0 1px 3px rgba(0,0,0,0.1)" : "none" }}>
                {window.L("Mensuel", "Monthly", "Mensual")}
              </button>
              <button onClick={() => setCycle("yearly")}
                style={{ padding: "8px 18px", border: "none", borderRadius: 999, background: cycle === "yearly" ? "white" : "transparent", color: cycle === "yearly" ? "#0f172a" : "#64748b", fontWeight: 600, cursor: "pointer", fontSize: 13, boxShadow: cycle === "yearly" ? "0 1px 3px rgba(0,0,0,0.1)" : "none" }}>
                {window.L("Annuel", "Yearly", "Anual")}
                <span style={{ marginLeft: 6, padding: "2px 7px", background: "#dcfce7", color: "#15803d", borderRadius: 999, fontSize: 10.5, fontWeight: 700 }}>
                  −2 {window.L("mois", "months", "meses")}
                </span>
              </button>
            </div>
          </div>

          {/* Plans columns */}
          {loading ? (
            <div style={{ textAlign: "center", padding: 60, color: "#64748b" }}>{window.L("Chargement des plans…", "Loading plans…", "Cargando los planes…")}</div>
          ) : (
            <div style={{ display: "grid", gridTemplateColumns: "repeat(" + Math.min(colCount, 3) + ", 1fr)", gap: 20, marginBottom: 48 }}>
              {(plans || []).map((plan) => {
                const isHighlight = !!plan.highlight;
                const priceCents = cycle === "yearly" ? plan.price_yearly : plan.price_monthly;
                const priceLabel = fmtPrice(priceCents, currency);
                const isFree = plan.code === "free";
                const isEnterprise = plan.code === "enterprise";
                const ctaLabel = isFree
                  ? (window.L("Commencer gratuitement", "Start for free", "Empezar gratis"))
                  : isEnterprise
                    ? (window.L("Demander un devis", "Request a quote", "Solicitar un presupuesto"))
                    : (window.L("S'abonner", "Subscribe", "Suscribirse"));
                return (
                  <div key={plan.code}
                    style={{
                      background: "white",
                      border: "2px solid " + (isHighlight ? "#0f766e" : "#e2e8f0"),
                      borderRadius: 14, padding: "26px 22px",
                      position: "relative",
                      boxShadow: isHighlight ? "0 12px 30px rgba(15,118,110,0.15)" : "0 1px 3px rgba(0,0,0,0.05)",
                      display: "flex", flexDirection: "column",
                    }}>
                    {isHighlight && (
                      <div style={{ position: "absolute", top: -12, left: "50%", transform: "translateX(-50%)", padding: "4px 12px", background: "#0f766e", color: "white", borderRadius: 999, fontSize: 11, fontWeight: 700, letterSpacing: "0.04em" }}>
                        {window.L("★ RECOMMANDÉ", "★ RECOMMENDED", "★ RECOMENDADO")}
                      </div>
                    )}
                    <div style={{ fontSize: 18, fontWeight: 700, marginBottom: 6 }}>
                      {(lang === "es" ? (plan.display_name_es != null ? plan.display_name_es : plan.display_name_en) : lang === "fr" ? plan.display_name_fr : plan.display_name_en)}
                    </div>
                    <div style={{ fontSize: 13, color: "#64748b", marginBottom: 18, minHeight: 38, lineHeight: 1.45 }}>
                      {(lang === "es" ? (plan.description_es != null ? plan.description_es : plan.description_en) : lang === "fr" ? plan.description_fr : plan.description_en)}
                    </div>
                    {/* Price */}
                    <div style={{ marginBottom: 20, minHeight: 60 }}>
                      {isEnterprise ? (
                        <div style={{ fontSize: 28, fontWeight: 800 }}>
                          {window.L("Sur devis", "Custom", "A medida")}
                        </div>
                      ) : isFree ? (
                        <div>
                          <div style={{ fontSize: 36, fontWeight: 800, lineHeight: 1 }}>0</div>
                          <div style={{ fontSize: 12, color: "#64748b", marginTop: 4 }}>{window.L("Sans carte bancaire", "No credit card", "Sin tarjeta bancaria")}</div>
                        </div>
                      ) : (
                        <div>
                          <div style={{ display: "flex", alignItems: "baseline", gap: 6 }}>
                            <span style={{ fontSize: 36, fontWeight: 800, lineHeight: 1 }}>{priceLabel || "—"}</span>
                            <span style={{ fontSize: 13, color: "#64748b" }}>
                              / {cycle === "yearly" ? (window.L("an", "year", "año")) : (window.L("mois", "month", "mes"))}
                            </span>
                          </div>
                          {cycle === "yearly" && plan.price_monthly > 0 && (
                            <div style={{ fontSize: 11, color: "#15803d", marginTop: 4, fontWeight: 600 }}>
                              {window.L("Soit " + fmtPrice(Math.round(plan.price_yearly / 12), currency) + " / mois", "≈ " + fmtPrice(Math.round(plan.price_yearly / 12), currency) + " / month", "≈ " + fmtPrice(Math.round(plan.price_yearly / 12), currency) + " / mes")}
                            </div>
                          )}
                        </div>
                      )}
                    </div>
                    {/* CTA */}
                    <button onClick={() => onSubscribe(plan)}
                      style={{
                        padding: "12px 16px", borderRadius: 8, border: "none",
                        background: isHighlight ? "#0f766e" : isFree ? "white" : "#0f172a",
                        color: isHighlight ? "white" : isFree ? "#0f172a" : "white",
                        fontSize: 14, fontWeight: 700, cursor: "pointer", marginBottom: 22,
                        boxShadow: isFree ? "inset 0 0 0 2px #cbd5e1" : "0 2px 6px rgba(0,0,0,0.1)",
                      }}>
                      {ctaLabel}
                    </button>
                    {/* Limits + features */}
                    <div style={{ fontSize: 12.5, color: "#475569", display: "flex", flexDirection: "column", gap: 6, paddingTop: 16, borderTop: "1px dashed #e2e8f0" }}>
                      <div style={{ fontWeight: 700, color: "#0f172a", marginBottom: 4, fontSize: 11.5, textTransform: "uppercase", letterSpacing: "0.05em" }}>
                        {window.L("Inclus", "Included", "Incluido")}
                      </div>
                      <Limit k="projects"   v={plan.max_projects}   lang={lang} />
                      <Limit k="users"      v={plan.max_users}      lang={lang} />
                      <Limit k="indicators" v={plan.max_indicators} lang={lang} />
                      <Limit k="sites"      v={plan.max_sites}      lang={lang} />
                      <Limit k="storage"    v={plan.max_storage_mb} lang={lang} suffix="MB" />
                      {plan.monthly_exports != null && (
                        <Limit k="exports" v={plan.monthly_exports} lang={lang} suffix={window.L("/mois", "/mo", "/mes")} />
                      )}
                      <div style={{ height: 6 }} />
                      {FEATURE_CATALOG.filter((f) => hasFeatureIn(plan, f.code)).map((f) => (
                        <div key={f.code} style={{ display: "flex", alignItems: "flex-start", gap: 6 }}>
                          <span style={{ color: "#15803d", fontWeight: 700 }}>✓</span>
                          <span>{(lang === "es" ? (f.es != null ? f.es : f.en) : lang === "fr" ? f.fr : f.en)}</span>
                        </div>
                      ))}
                    </div>
                  </div>
                );
              })}
            </div>
          )}

          {/* FAQ */}
          <div style={{ background: "white", border: "1px solid #e2e8f0", borderRadius: 12, padding: "28px 32px", marginBottom: 24 }}>
            <h2 style={{ fontSize: 22, fontWeight: 700, margin: "0 0 18px" }}>FAQ</h2>
            <div style={{ display: "grid", gap: 14 }}>
              <FaqItem
                q={window.L("Puis-je changer de plan à tout moment ?", "Can I change plans at any time?", "¿Puedo cambiar de plan en cualquier momento?")}
                a={window.L("Oui. Vous pouvez upgrader ou downgrader depuis Paramètres → Facturation. Les changements sont au prorata.", "Yes. Upgrade or downgrade from Settings → Billing. Changes are prorated.", "Sí. Puede mejorar o reducir su plan desde Ajustes → Facturación. Los cambios son a prorrata.")} />
              <FaqItem
                q={window.L("Quels moyens de paiement acceptez-vous ?", "Which payment methods do you accept?", "¿Qué métodos de pago aceptan?")}
                a={window.L("Cartes bancaires (Visa, Mastercard, Amex) via Stripe pour le plan Pro. Virement bancaire pour le plan Enterprise.", "Credit cards (Visa, Mastercard, Amex) via Stripe for Pro. Bank transfer for Enterprise.", "Tarjetas bancarias (Visa, Mastercard, Amex) mediante Stripe para el plan Pro. Transferencia bancaria para el plan Enterprise.")} />
              <FaqItem
                q={window.L("Mes données m'appartiennent-elles ?", "Do I own my data?", "¿Son míos mis datos?")}
                a={window.L("100 % oui. Vous pouvez exporter toutes vos données (CSV, Word, PDF) à tout moment. Aucun verrouillage propriétaire.", "100% yes. You can export everything (CSV, Word, PDF) anytime. No vendor lock-in.", "100 % sí. Puede exportar todos sus datos (CSV, Word, PDF) en cualquier momento. Sin bloqueo propietario.")} />
              <FaqItem
                q={window.L("Où mes données sont-elles hébergées ?", "Where is my data hosted?", "¿Dónde se alojan mis datos?")}
                a={window.L("Par défaut sur Supabase (UE). Le plan Enterprise permet un hébergement souverain (Afrique de l'Ouest, France, Maroc) sur demande.", "By default on Supabase (EU). Enterprise allows sovereign hosting (West Africa, France, Morocco) on request.", "Por defecto en Supabase (UE). El plan Enterprise permite un alojamiento soberano (África Occidental, Francia, Marruecos) a petición.")} />
              <FaqItem
                q={window.L("Y a-t-il un essai gratuit du plan Pro ?", "Is there a free trial of the Pro plan?", "¿Hay una prueba gratuita del plan Pro?")}
                a={window.L("Le plan Free est disponible sans limite de durée. Pour évaluer les fonctionnalités Pro, contactez-nous pour une démo personnalisée de 14 jours.", "The Free plan is available forever. For a Pro feature evaluation, contact us for a 14-day personalized demo.", "El plan Free está disponible sin límite de tiempo. Para evaluar las funciones Pro, contáctenos para una demo personalizada de 14 días.")} />
              <FaqItem
                q={window.L("Comment fonctionne la facturation en XOF ?", "How does XOF billing work?", "¿Cómo funciona la facturación en XOF?")}
                a={window.L("Pour les organisations de l'UEMOA (Sénégal, Côte d'Ivoire, Mali, Burkina Faso…), nous proposons le tarif en F CFA via virement bancaire local. Contactez-nous.", "For UEMOA organizations (Senegal, Côte d'Ivoire, Mali, Burkina Faso…), we offer XOF pricing via local bank transfer. Contact us.", "Para las organizaciones de la UEMOA (Senegal, Côte d'Ivoire, Mali, Burkina Faso…), ofrecemos la tarifa en FCFA mediante transferencia bancaria local. Contáctenos.")} />
            </div>
          </div>

          {/* Méthodes de paiement acceptées (icônes en bas de page) */}
          <AcceptedPaymentsStrip lang={lang} currency={currency} />

          {/* Footer */}
          <div style={{ textAlign: "center", color: "#64748b", fontSize: 12.5 }}>
            <p style={{ margin: "0 0 6px" }}>
              {window.L("Questions ? Écrivez à ", "Questions? Email ", "¿Preguntas? Escriba a ")}
              <a href="mailto:it@reft-africa.org" style={{ color: "#0f766e" }}>it@reft-africa.org</a>
            </p>
            <p style={{ margin: 0 }}>
              MELR — REFT Africa · <a href="/MELR" style={{ color: "#0f766e" }}>{window.L("Application", "App", "Aplicación")}</a>
              · <a href="https://www.reft-africa.org/melr-demo/" style={{ color: "#0f766e" }}>{window.L("Démo en ligne", "Live demo", "Demo en línea")}</a>
            </p>
          </div>
        </div>

        {/* Modal : choix du moyen de paiement après clic sur S'abonner */}
        {methodPicker && (
          <PaymentMethodPicker lang={lang} currency={currency} plan={methodPicker.plan}
            onClose={() => setMethodPicker(null)}
            onChoose={(m) => onMethodChosen(m, methodPicker.plan)} />
        )}
        {/* Modal : instructions manuelles (Orange Money / Wave / virement) */}
        {methodModal && (
          <PaymentInstructionsModal lang={lang} method={methodModal.method} plan={methodModal.plan}
            onClose={() => setMethodModal(null)} />
        )}
      </div>
    );
  }

  // Strip d'icônes en bas de page : montre les méthodes activées + filtrées
  // par la devise courante. Pas d'action, juste pour la confiance.
  function AcceptedPaymentsStrip({ lang, currency }) {
    const { data: methods, loading } = window.melr.usePaymentMethods({ enabledOnly: true, currency });
    if (loading || !methods || methods.length === 0) return null;
    return (
      <div style={{ textAlign: "center", marginBottom: 28, padding: "20px 24px", background: "white", borderRadius: 10, border: "1px solid #e2e8f0" }}>
        <div style={{ fontSize: 11, color: "#64748b", textTransform: "uppercase", letterSpacing: "0.08em", fontWeight: 700, marginBottom: 10 }}>
          {window.L("Moyens de paiement acceptés", "Accepted payment methods", "Métodos de pago aceptados")}
        </div>
        <div style={{ display: "flex", justifyContent: "center", gap: 18, flexWrap: "wrap" }}>
          {methods.map((m) => (
            <div key={m.code} title={(lang === "es" ? (m.display_name_es != null ? m.display_name_es : m.display_name_en) : lang === "fr" ? m.display_name_fr : m.display_name_en)}
              style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 4, minWidth: 70 }}>
              <span style={{ fontSize: 28 }}>{m.icon_emoji || "💳"}</span>
              <span style={{ fontSize: 11, fontWeight: 600, color: "#475569" }}>
                {(lang === "es" ? (m.display_name_es != null ? m.display_name_es : m.display_name_en) : lang === "fr" ? m.display_name_fr : m.display_name_en)}
              </span>
            </div>
          ))}
        </div>
      </div>
    );
  }

  // Modal · liste les moyens de paiement compatibles avec le plan + devise.
  // L'user clique sur celui qu'il veut → ouvre l'action (Stripe / URL / instructions)
  function PaymentMethodPicker({ lang, currency, plan, onClose, onChoose }) {
    const { data: methods, loading } = window.melr.usePaymentMethods({
      enabledOnly: true, currency, planCode: plan.code,
    });
    const Modal = window.Modal;
    return (
      <Modal lang={lang}
        title={window.L("Comment souhaitez-vous payer ?", "How would you like to pay?", "¿Cómo desea pagar?")}
        onClose={onClose}>
        <div style={{ marginBottom: 14, fontSize: 13, color: "#475569" }}>
          {window.L(<>Vous vous abonnez au plan <strong>{plan.display_name_fr}</strong> en <strong>{currency}</strong>. Choisissez votre moyen de paiement préféré :</>, <>You're subscribing to <strong>{plan.display_name_en}</strong> in <strong>{currency}</strong>. Pick your preferred payment method:</>, <>Se suscribe al plan <strong>{plan.display_name_en}</strong> en <strong>{currency}</strong>. Elija su método de pago preferido:</>)}
        </div>
        {loading && <div style={{ color: "#64748b" }}>{window.L("Chargement…", "Loading…", "Cargando…")}</div>}
        {!loading && methods.length === 0 && (
          <div style={{ padding: 24, textAlign: "center", color: "#dc2626", background: "#fee2e2", borderRadius: 8 }}>
            {window.L("Aucun moyen de paiement n'est configuré pour ce plan dans cette devise. Écrivez à it@reft-africa.org.", "No payment method is configured for this plan in this currency. Email it@reft-africa.org.", "No hay ningún método de pago configurado para este plan en esta moneda. Escriba a it@reft-africa.org.")}
          </div>
        )}
        <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
          {methods.map((m) => (
            <button key={m.code} onClick={() => onChoose(m)}
              style={{
                width: "100%", textAlign: "left",
                padding: "14px 16px", borderRadius: 10,
                background: "white", border: "2px solid #e2e8f0",
                cursor: "pointer", display: "flex", alignItems: "center", gap: 14,
                transition: "border-color 100ms",
              }}
              onMouseEnter={(e) => e.currentTarget.style.borderColor = "#0f766e"}
              onMouseLeave={(e) => e.currentTarget.style.borderColor = "#e2e8f0"}>
              <span style={{ fontSize: 32 }}>{m.icon_emoji || "💳"}</span>
              <div style={{ flex: 1 }}>
                <div style={{ fontWeight: 700, fontSize: 14, color: "#0f172a" }}>
                  {(lang === "es" ? (m.display_name_es != null ? m.display_name_es : m.display_name_en) : lang === "fr" ? m.display_name_fr : m.display_name_en)}
                </div>
                <div style={{ fontSize: 12, color: "#64748b", marginTop: 2 }}>
                  {(lang === "es" ? (m.description_es != null ? m.description_es : m.description_en) : lang === "fr" ? m.description_fr : m.description_en)}
                </div>
              </div>
              <span style={{ color: "#0f766e", fontWeight: 700, fontSize: 18 }}>→</span>
            </button>
          ))}
        </div>
      </Modal>
    );
  }

  // Modal d'instructions pour les moyens « manual » (Orange Money, Wave,
  // virement…). Affiche les instructions multilingues avec rendu Markdown
  // minimal (gras + monospace inline).
  function PaymentInstructionsModal({ lang, method, plan, onClose }) {
    const Modal = window.Modal;
    const raw = ((lang === "es" ? (method.instructions_es != null ? method.instructions_es : method.instructions_en) : lang === "fr" ? method.instructions_fr : method.instructions_en)) || "";
    // Rendu Markdown ultra-léger : gras **x**, code `x`, liens [x](y),
    // paragraphes séparés par \n\n. Pas de bibliothèque externe.
    const renderMarkdown = (md) => {
      const blocks = md.split(/\n\n+/);
      return blocks.map((b, i) => {
        const html = b
          .replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")
          .replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>")
          .replace(/`([^`]+)`/g, "<code style=\"background:#f1f5f9;padding:1px 6px;border-radius:4px;font-family:monospace;font-size:13px;\">$1</code>")
          .replace(/\[(.+?)\]\((.+?)\)/g, '<a href="$2" style="color:#0f766e;text-decoration:underline;">$1</a>')
          .replace(/_(.+?)_/g, "<em>$1</em>")
          .replace(/\n/g, "<br />");
        return <p key={i} style={{ margin: "0 0 12px", lineHeight: 1.6, fontSize: 13.5 }} dangerouslySetInnerHTML={{ __html: html }} />;
      });
    };
    return (
      <Modal lang={lang}
        title={(method.icon_emoji || "💳") + " " + ((lang === "es" ? (method.display_name_es != null ? method.display_name_es : method.display_name_en) : lang === "fr" ? method.display_name_fr : method.display_name_en))}
        onClose={onClose}>
        <div style={{ marginBottom: 14, padding: "10px 14px", background: "#fef3c7", borderRadius: 8, border: "1px solid #fcd34d", fontSize: 13 }}>
          <strong>{window.L("Plan : ", "Plan: ", "Plan: ")}</strong>{(lang === "es" ? (plan.display_name_es != null ? plan.display_name_es : plan.display_name_en) : lang === "fr" ? plan.display_name_fr : plan.display_name_en)}
        </div>
        <div style={{ color: "#0f172a" }}>
          {raw ? renderMarkdown(raw) : (
            <p style={{ color: "#64748b", fontStyle: "italic" }}>
              {window.L("Aucune instruction n'a été renseignée. Contactez it@reft-africa.org pour les détails.", "No instructions have been set. Contact it@reft-africa.org for details.", "No se ha indicado ninguna instrucción. Contacte con it@reft-africa.org para más detalles.")}
            </p>
          )}
        </div>
        <div style={{ marginTop: 18, padding: "10px 14px", background: "#dcfce7", borderRadius: 8, border: "1px solid #86efac", fontSize: 12 }}>
          <strong style={{ color: "#065f46" }}>{window.L("Une fois le paiement effectué :", "Once paid:", "Una vez efectuado el pago:")}</strong>
          {" "}
          {window.L(<>écrivez à <a href="mailto:it@reft-africa.org" style={{ color: "#0f766e", fontWeight: 700 }}>it@reft-africa.org</a> avec votre justificatif. Votre abonnement sera activé sous 24 h ouvrées.</>, <>email <a href="mailto:it@reft-africa.org" style={{ color: "#0f766e", fontWeight: 700 }}>it@reft-africa.org</a> with your proof. Your subscription will be activated within 24 business hours.</>, <>escriba a <a href="mailto:it@reft-africa.org" style={{ color: "#0f766e", fontWeight: 700 }}>it@reft-africa.org</a> con su justificante. Su suscripción se activará en un plazo de 24 horas hábiles.</>)}
        </div>
        <div style={{ display: "flex", justifyContent: "flex-end", marginTop: 18 }}>
          <button onClick={onClose} className="btn primary">
            {window.L("Fermer", "Close", "Cerrar")}
          </button>
        </div>
      </Modal>
    );
  }

  // Composant ligne de limite ("✓ 25 projets" / "✓ Illimité")
  function Limit({ k, v, lang, suffix }) {
    const labels = {
      projects:   { fr: "projets",     en: "projects", es: "proyectos" },
      users:      { fr: "utilisateurs", en: "users", es: "usuarios" },
      indicators: { fr: "indicateurs", en: "indicators", es: "indicadores" },
      sites:      { fr: "sites",       en: "sites", es: "sitios" },
      storage:    { fr: "stockage",    en: "storage", es: "almacenamiento" },
      exports:    { fr: "exports",     en: "exports", es: "exportaciones" },
    };
    const lbl = labels[k] || { fr: k, en: k };
    const text = v == null
      ? (window.L("Illimité ", "Unlimited ", "Ilimitado ")) + ((lang === "es" ? (lbl.es != null ? lbl.es : lbl.en) : lang === "fr" ? lbl.fr : lbl.en))
      : v + " " + ((lang === "es" ? (lbl.es != null ? lbl.es : lbl.en) : lang === "fr" ? lbl.fr : lbl.en)) + (suffix ? " " + suffix : "");
    return (
      <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
        <span style={{ color: "#0f766e", fontWeight: 700 }}>✓</span>
        <span>{text}</span>
      </div>
    );
  }

  function FaqItem({ q, a }) {
    const [open, setOpen] = useState(false);
    return (
      <div style={{ borderBottom: "1px solid #e2e8f0", paddingBottom: 12 }}>
        <button onClick={() => setOpen(!open)}
          style={{ width: "100%", textAlign: "left", padding: "6px 0", border: "none", background: "transparent", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12 }}>
          <span style={{ fontWeight: 600, fontSize: 14 }}>{q}</span>
          <span style={{ color: "#94a3b8", fontSize: 18 }}>{open ? "−" : "+"}</span>
        </button>
        {open && <div style={{ marginTop: 6, color: "#475569", fontSize: 13.5, lineHeight: 1.55 }}>{a}</div>}
      </div>
    );
  }

  window.PricingPage = PricingPage;
})();
