/* SuperAdmin → window. Panel de superadmin.
   Se renderiza INLINE como una pestaña más (no overlay) — la BottomNav y el
   Header de la app permanecen visibles. El modal de generar y el toast sí
   son portals porque deben cubrir todo.
   Props: { iglesias }
   Tabs: iglesias | pastores | invitaciones | solicitudes
   - Genera invitaciones tipo pastor, miembro o amigo — persiste en RTDB vía
     window.crearInvitacion(). Suscribe a /invitaciones para la lista.
   - Tab "Solicitudes" lista /solicitudes_pastor con estado="pendiente";
     aprobar hace multi-path (estado="aprobada" + users/{uid}/perfil/tipo="pastor");
     rechazar guarda razon_rechazo. */
(function () {
  const { useState, useEffect, useMemo, useRef } = React;
  const { useAuth, useTheme } = window;
  const getConfirmModal = function () { return window.ConfirmModal; };

  const BRAND = "#2563EB";
  const BRAND_DARK = "#1E4ED8";
  const GREEN = "#58CC02";
  const GREEN_SHADOW = "#46A302";
  const AMBER = "#FFC800";
  const DANGER = "#FF4B4B";
  const INK = "#3C3C3C";
  const MUTED = "#777";
  const DIVIDER = "#EEE";
  const PANEL_BG = "#F9F9F9";

  // Los enlaces que generamos SIEMPRE apuntan al dominio oficial, aunque se
  // generen desde localhost. El user los va a compartir por WhatsApp/IG y
  // deben lucir como enlaces reales de la app.
  const PROD_HOST = "cultord-397bc.web.app";
  const PROD_ORIGIN = "https://" + PROD_HOST;

  const OPCIONES_EXPIRACION = [
    { id: "1h",   label: "1 hora",    ms: 60 * 60 * 1000 },
    { id: "6h",   label: "6 horas",   ms: 6 * 60 * 60 * 1000 },
    { id: "24h",  label: "24 horas",  ms: 24 * 60 * 60 * 1000 },
    { id: "7d",   label: "7 días",    ms: 7 * 24 * 60 * 60 * 1000 },
    { id: "inf",  label: "Indefinido", ms: null },
  ];

  // --- Helpers compartidos ---

  function formatoCodigo(c) {
    const s = String(c || "").padStart(6, "0").slice(0, 6);
    return s.slice(0, 3) + " " + s.slice(3);
  }

  function formatoTiempoRestante(ms) {
    if (ms == null) return "Sin expiración";
    if (ms <= 0) return "Expiró";
    const seg = Math.floor(ms / 1000);
    const min = Math.floor(seg / 60);
    const hr  = Math.floor(min / 60);
    const d   = Math.floor(hr / 24);
    if (d >= 1) return d + "d " + (hr % 24) + "h";
    if (hr >= 1) return hr + "h " + (min % 60) + "m";
    if (min >= 1) return min + "m";
    return seg + "s";
  }

  function pillTiempo(msRestantes, expiraEn) {
    // Indefinido → verde claro
    if (expiraEn == null) return { bg: "#E6F6D5", fg: "#2E7D13", label: "Sin expiración" };
    const UNA_HORA = 60 * 60 * 1000;
    const UN_DIA   = 24 * UNA_HORA;
    if (msRestantes <= 0) return { bg: "#FFE4E4", fg: "#B32020", label: "Expiró" };
    if (msRestantes < UNA_HORA) return { bg: DANGER, fg: "#FFFFFF", label: formatoTiempoRestante(msRestantes) };
    if (msRestantes < UN_DIA)   return { bg: AMBER,  fg: "#3C3C3C", label: formatoTiempoRestante(msRestantes) };
    return { bg: GREEN, fg: "#FFFFFF", label: formatoTiempoRestante(msRestantes) };
  }

  async function copiarAlClipboard(texto) {
    try {
      if (navigator.clipboard && navigator.clipboard.writeText) {
        await navigator.clipboard.writeText(texto);
        return true;
      }
    } catch (_) { /* noop → fallback abajo */ }
    try {
      const el = document.createElement("textarea");
      el.value = texto;
      el.setAttribute("readonly", "");
      el.style.position = "fixed";
      el.style.top = "-1000px";
      document.body.appendChild(el);
      el.select();
      const ok = document.execCommand("copy");
      document.body.removeChild(el);
      return ok;
    } catch (_) {
      return false;
    }
  }

  async function compartirLink(titulo, texto, url) {
    if (navigator.share) {
      try {
        await navigator.share({ title: titulo, text: texto, url: url });
        return "nativo";
      } catch (e) {
        if (e && e.name === "AbortError") return "cancelado";
      }
    }
    const ok = await copiarAlClipboard(url);
    return ok ? "copiado" : "error";
  }

  function compartirWhatsApp(texto, url) {
    const mensaje = (texto ? texto + "\n\n" : "") + url;
    const wa = "https://wa.me/?text=" + encodeURIComponent(mensaje);
    try {
      window.open(wa, "_blank", "noopener,noreferrer");
      return true;
    } catch (_) {
      return false;
    }
  }

  // --- Componente ---

  function SuperAdmin({ iglesias }) {
    const { user } = useAuth();
    const { dark } = useTheme();
    const colorTexto = dark ? "#F0F0F0" : INK;
    const colorSecundario = dark ? "#9CA3AF" : MUTED;
    const colorBorde = dark ? "#2A2A2A" : DIVIDER;
    const bgPanel = dark ? "#141415" : PANEL_BG;
    const bgCard = dark ? "#1A1A1A" : "#FFFFFF";
    const bgHeader = dark ? "#0F0F10" : "#FFFFFF";
    const bgTabs = dark ? "#1F2937" : "#F0F0F0";
    const bgMono = dark ? "#1F2937" : "#F4F6FB";
    const bgInfoBox = dark ? "#141415" : "#F9FAFB";
    const shadowCard = dark ? "0 1px 0 #2A2A2A" : "0 1px 0 " + DIVIDER;
    const [tabActiva, setTabActiva] = useState("iglesias");
    // "" (cerrado) | "pastor" | "miembro" | "amigo"
    const [modalTipo, setModalTipo] = useState("");
    const [ahora, setAhora] = useState(Date.now());
    const [toast, setToast] = useState("");
    const [invitaciones, setInvitaciones] = useState([]);
    const [solicitudes, setSolicitudes] = useState([]);
    // Reclamos de iglesias no reclamadas.
    const [reclamos, setReclamos] = useState([]);
    const [aprobandoRec, setAprobandoRec] = useState(null);
    const [rechazandoRec, setRechazandoRec] = useState(null);
    // Acciones sobre solicitudes.
    const [aprobandoSol, setAprobandoSol] = useState(null); // sol completa o null
    const [rechazandoSol, setRechazandoSol] = useState(null);
    const [accionEnCurso, setAccionEnCurso] = useState(false);
    // Eliminar invitación (objeto completo o null).
    const [eliminandoInv, setEliminandoInv] = useState(null);
    const [eliminandoEnCurso, setEliminandoEnCurso] = useState(false);

    useEffect(function () {
      const t = setInterval(function () { setAhora(Date.now()); }, 30000);
      return function () { clearInterval(t); };
    }, []);

    useEffect(function () {
      if (typeof window.suscribirInvitaciones !== "function") return;
      const unsub = window.suscribirInvitaciones(function (arr) {
        setInvitaciones(Array.isArray(arr) ? arr : []);
      });
      return unsub;
    }, []);

    useEffect(function () {
      if (typeof window.suscribirSolicitudesPendientes !== "function") return;
      const unsub = window.suscribirSolicitudesPendientes(function (arr) {
        setSolicitudes(Array.isArray(arr) ? arr : []);
      });
      return unsub;
    }, []);

    useEffect(function () {
      if (typeof window.suscribirReclamosPendientes !== "function") return;
      const unsub = window.suscribirReclamosPendientes(function (arr) {
        setReclamos(Array.isArray(arr) ? arr : []);
      });
      return unsub;
    }, []);

    const solicitudesOrdenadas = useMemo(function () {
      return solicitudes.slice().sort(function (a, b) {
        return (b.creado_en || 0) - (a.creado_en || 0);
      });
    }, [solicitudes]);

    async function ejecutarAprobar(sol) {
      if (!sol || !sol.uid || !window.db) return;
      setAccionEnCurso(true);
      try {
        const TS = firebase.database.ServerValue.TIMESTAMP;
        const updates = {};
        updates["solicitudes_pastor/" + sol.uid + "/estado"] = "aprobada";
        updates["solicitudes_pastor/" + sol.uid + "/revisado_por"] = (user && user.uid) || "";
        updates["solicitudes_pastor/" + sol.uid + "/revisado_en"] = TS;
        updates["users/" + sol.uid + "/perfil/tipo"] = "pastor";
        await window.db.ref().update(updates);
        mostrarToast("Pastor aprobado ✓");
        setAprobandoSol(null);
      } catch (e) {
        console.warn("[SuperAdmin] aprobar falló:", e);
        mostrarToast("No pudimos aprobar. " + (e && e.message ? e.message : ""));
      } finally {
        setAccionEnCurso(false);
      }
    }

    async function ejecutarRechazar(sol, razon) {
      if (!sol || !sol.uid || !window.db) return;
      const texto = String(razon || "").trim();
      if (!texto) return;
      setAccionEnCurso(true);
      try {
        const TS = firebase.database.ServerValue.TIMESTAMP;
        const updates = {};
        updates["solicitudes_pastor/" + sol.uid + "/estado"] = "rechazada";
        updates["solicitudes_pastor/" + sol.uid + "/razon_rechazo"] = texto.slice(0, 500);
        updates["solicitudes_pastor/" + sol.uid + "/revisado_por"] = (user && user.uid) || "";
        updates["solicitudes_pastor/" + sol.uid + "/revisado_en"] = TS;
        await window.db.ref().update(updates);
        mostrarToast("Solicitud rechazada");
        setRechazandoSol(null);
      } catch (e) {
        console.warn("[SuperAdmin] rechazar falló:", e);
        mostrarToast("No pudimos rechazar. " + (e && e.message ? e.message : ""));
      } finally {
        setAccionEnCurso(false);
      }
    }

    async function ejecutarEliminarInvitacion(inv) {
      if (!inv || !inv.codigo || typeof window.eliminarInvitacion !== "function") return;
      setEliminandoEnCurso(true);
      try {
        await window.eliminarInvitacion(inv.codigo);
        mostrarToast("Invitación eliminada ✓");
        setEliminandoInv(null);
      } catch (e) {
        console.warn("[SuperAdmin] eliminar invitación falló:", e);
        mostrarToast("No pudimos eliminar. " + (e && e.message ? e.message : ""));
      } finally {
        setEliminandoEnCurso(false);
      }
    }

    function mostrarToast(msg) {
      setToast(msg);
      setTimeout(function () { setToast(""); }, 1600);
    }

    const iglesiasOrdenadas = useMemo(function () {
      const arr = Array.isArray(iglesias) ? iglesias.slice() : [];
      arr.sort(function (a, b) { return String(a.nombre || "").localeCompare(String(b.nombre || "")); });
      return arr;
    }, [iglesias]);

    const invitacionesTodas = useMemo(function () {
      return invitaciones.slice().sort(function (a, b) {
        const ta = (a && (a.creado_en || a.expira_en)) || 0;
        const tb = (b && (b.creado_en || b.expira_en)) || 0;
        return tb - ta;
      });
    }, [invitaciones]);

    if (typeof document === "undefined") return null;

    return (
      <div
        className="fade-in"
        style={{
          background: bgPanel, color: colorTexto,
          paddingBottom: 84, // espacio para el BottomNav
          animation: "superFade 180ms ease-out",
        }}
      >
        {/* Cabecera interna (no sticky): título + tabs pill */}
        <div style={{
          background: bgHeader,
          borderBottom: "1px solid " + colorBorde,
          padding: "12px 14px 10px",
        }}>
          <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 12 }}>
            <div style={{ fontSize: 22, lineHeight: 1 }} aria-hidden="true">👑</div>
            <div style={{ fontSize: 17, fontWeight: 900, color: colorTexto }}>Panel Superadmin</div>
          </div>

          <div style={{ display: "flex", gap: 6, background: bgTabs, borderRadius: 999, padding: 4 }}>
            {[
              { id: "iglesias",     label: "Iglesias" },
              { id: "pastores",     label: "Pastores" },
              { id: "invitaciones", label: "Invitaciones" },
              { id: "solicitudes",  label: "Solicitudes", badge: solicitudes.length },
              { id: "reclamos",     label: "Reclamos",    badge: reclamos.length },
            ].map(function (t) {
              const active = tabActiva === t.id;
              const badge = typeof t.badge === "number" && t.badge > 0 ? t.badge : 0;
              return (
                <button
                  key={t.id}
                  type="button"
                  onClick={function () { setTabActiva(t.id); }}
                  style={{
                    flex: 1, height: 34, border: "none", borderRadius: 999,
                    background: active ? BRAND : "transparent",
                    color: active ? "#FFFFFF" : colorSecundario,
                    fontSize: 12, fontWeight: 800, cursor: "pointer",
                    transition: "background 150ms, color 150ms",
                    display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 4,
                    padding: "0 6px",
                  }}
                >
                  <span>{t.label}</span>
                  {badge > 0 && (
                    <span style={{
                      minWidth: 18, height: 18, borderRadius: 999,
                      background: active ? "#FFFFFF" : DANGER,
                      color: active ? DANGER : "#FFFFFF",
                      fontSize: 11, fontWeight: 900,
                      display: "inline-flex", alignItems: "center", justifyContent: "center",
                      padding: "0 5px",
                    }}>{badge}</span>
                  )}
                </button>
              );
            })}
          </div>
        </div>

        {/* Contenido (fade al cambiar tab) */}
        <div key={tabActiva} style={{ padding: "14px", animation: "superFade 180ms ease-out" }}>
          {tabActiva === "iglesias"     && renderTabIglesias(iglesiasOrdenadas)}
          {tabActiva === "pastores"     && renderTabPastores()}
          {tabActiva === "invitaciones" && renderTabInvitaciones()}
          {tabActiva === "solicitudes"  && renderTabSolicitudes()}
          {tabActiva === "reclamos"     && renderTabReclamos()}
        </div>

        {modalTipo && (
          <ModalGenerarInvitacion
            tipo={modalTipo}
            user={user}
            onCerrar={function () { setModalTipo(""); }}
            onCopiar={copiarAlClipboard}
            onCompartir={compartirLink}
            onToast={mostrarToast}
          />
        )}

        {getConfirmModal() && React.createElement(getConfirmModal(), {
          abierto: !!aprobandoSol,
          titulo: "Aprobar solicitud",
          mensaje: aprobandoSol
            ? "¿Aprobar a " + (aprobandoSol.nombre_completo || "este usuario") + " como pastor? Su perfil pasará a tipo pastor inmediatamente."
            : "",
          textoConfirmar: "Aprobar",
          textoCancelar: "Cancelar",
          cargando: accionEnCurso,
          onConfirmar: function () { ejecutarAprobar(aprobandoSol); },
          onCancelar: function () { if (!accionEnCurso) setAprobandoSol(null); },
        })}

        {rechazandoSol && (
          <RechazarSolicitudModal
            sol={rechazandoSol}
            cargando={accionEnCurso}
            onCancelar={function () { if (!accionEnCurso) setRechazandoSol(null); }}
            onConfirmar={function (razon) { ejecutarRechazar(rechazandoSol, razon); }}
          />
        )}

        {getConfirmModal() && React.createElement(getConfirmModal(), {
          abierto: !!eliminandoInv,
          titulo: "Eliminar invitación",
          mensaje: eliminandoInv
            ? "¿Eliminar el enlace " + formatoCodigo(eliminandoInv.codigo) + "? Quien lo tenga ya no podrá usarlo. Esta acción no se puede deshacer."
            : "",
          textoConfirmar: "Eliminar",
          textoCancelar: "Cancelar",
          tono: "peligro",
          cargando: eliminandoEnCurso,
          onConfirmar: function () { ejecutarEliminarInvitacion(eliminandoInv); },
          onCancelar: function () { if (!eliminandoEnCurso) setEliminandoInv(null); },
        })}

        {getConfirmModal() && React.createElement(getConfirmModal(), {
          abierto: !!aprobandoRec,
          titulo: "Aprobar reclamo",
          mensaje: aprobandoRec
            ? "¿Aprobar el reclamo de " + (aprobandoRec.nombre_pastor || aprobandoRec.email_pastor || "este pastor") + " sobre la iglesia " + (aprobandoRec.iglesia_nombre || aprobandoRec.iglesia_id) + "? La iglesia pasará a ser administrada por este pastor."
            : "",
          textoConfirmar: "Aprobar",
          textoCancelar: "Cancelar",
          cargando: accionEnCurso,
          onConfirmar: function () { ejecutarAprobarReclamo(aprobandoRec); },
          onCancelar: function () { if (!accionEnCurso) setAprobandoRec(null); },
        })}

        {getConfirmModal() && React.createElement(getConfirmModal(), {
          abierto: !!rechazandoRec,
          titulo: "Rechazar reclamo",
          mensaje: rechazandoRec
            ? "¿Rechazar el reclamo de " + (rechazandoRec.nombre_pastor || "este pastor") + "? La iglesia seguirá sin reclamar."
            : "",
          textoConfirmar: "Rechazar",
          textoCancelar: "Cancelar",
          tono: "peligro",
          cargando: accionEnCurso,
          onConfirmar: function () { ejecutarRechazarReclamo(rechazandoRec, ""); },
          onCancelar: function () { if (!accionEnCurso) setRechazandoRec(null); },
        })}

        {toast && (
          <div
            style={{
              position: "fixed", left: "50%", bottom: 96,
              transform: "translateX(-50%)",
              background: INK, color: "#FFF",
              padding: "12px 18px", borderRadius: 999,
              fontSize: 14, fontWeight: 700,
              boxShadow: "0 6px 20px rgba(0,0,0,0.25)",
              zIndex: 40,
              animation: "superFade 180ms ease-out",
            }}
          >{toast}</div>
        )}

        <style>{`
          @keyframes superFade { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }
          @keyframes superBounce { 0%,100% { transform: scale(1); } 40% { transform: scale(1.08); } 70% { transform: scale(0.97); } }
          .super-press { transition: transform 100ms ease, background 150ms ease; }
          .super-press:active { transform: translateY(1px); }
          .super-bounce { animation: superBounce 320ms ease; }
        `}</style>
      </div>
    );

    // ---------- Renderers de tabs ----------

    function renderTabIglesias(lista) {
      if (!lista || lista.length === 0) {
        return renderEmpty("Sin iglesias activas", "Aún no hay iglesias publicadas en la base de datos.");
      }
      return (
        <div>
          <div style={{ background: bgCard, borderRadius: 14, boxShadow: shadowCard }}>
            {lista.map(function (ig, idx) {
              const slots = Array.isArray(ig.horario) ? ig.horario.length : 0;
              const activa = ig.activa !== false;
              const noReclamada = ig.reclamada === false;
              return (
                <div
                  key={ig.id || idx}
                  style={{
                    display: "flex", alignItems: "flex-start", gap: 10,
                    padding: "12px 14px",
                    borderBottom: idx < lista.length - 1 ? "1px solid " + colorBorde : "none",
                  }}
                >
                  <div style={{
                    width: 40, height: 40, borderRadius: 10,
                    background: BRAND + "15", color: BRAND,
                    display: "flex", alignItems: "center", justifyContent: "center",
                    fontSize: 20, flexShrink: 0,
                  }} aria-hidden="true">🏠</div>

                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 15, fontWeight: 800, color: colorTexto, marginBottom: 2, wordBreak: "break-word" }}>
                      {ig.nombre || "(sin nombre)"}
                    </div>
                    <div style={{ fontSize: 12, color: colorSecundario, marginBottom: 6 }}>
                      por {ig.creado_por_nombre || "—"}
                    </div>
                    <div style={{ display: "flex", flexWrap: "wrap", gap: 6 }}>
                      <span style={badgePill(activa ? "#E6F6D5" : "#F3E3E3", activa ? "#2E7D13" : "#B32020")}>
                        {activa ? "Activa" : "Inactiva"}
                      </span>
                      {noReclamada && (
                        <span style={badgePill("#FEF3C7", "#92400E")}>No reclamada</span>
                      )}
                      <span style={badgePill("#E8EEFC", BRAND)}>
                        {slots === 1 ? "1 slot" : slots + " slots"}
                      </span>
                      {ig.verificada && (
                        <span style={badgePill("#FFF4CC", "#8A6700")}>Verificada</span>
                      )}
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      );
    }

    function renderTabPastores() {
      return renderEmpty(
        "Sin pastores registrados",
        "Cuando un pastor reclame su iglesia mediante un enlace de invitación, aparecerá aquí."
      );
    }

    function renderTabSolicitudes() {
      const lista = solicitudesOrdenadas;
      if (lista.length === 0) {
        return renderEmpty(
          "Sin solicitudes pendientes",
          "Cuando un usuario solicite registro como pastor, aparecerá aquí para que la revises."
        );
      }
      return (
        <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
          {lista.map(function (sol) {
            return (
              <ItemSolicitud
                key={sol.uid}
                sol={sol}
                onAprobar={function () { setAprobandoSol(sol); }}
                onRechazar={function () { setRechazandoSol(sol); }}
              />
            );
          })}
        </div>
      );
    }

    async function ejecutarAprobarReclamo(rec) {
      if (!rec || !rec.iglesia_id || !rec.uid) return;
      setAccionEnCurso(true);
      try {
        const auth = firebase.auth ? firebase.auth().currentUser : null;
        const uidRev = auth && auth.uid;
        if (!uidRev) throw new Error("Sin sesión.");
        await window.aprobarReclamo(rec.iglesia_id, rec.uid, uidRev);
        mostrarToast("Reclamo aprobado");
      } catch (e) {
        console.warn("[SuperAdmin] aprobarReclamo falló:", e);
        mostrarToast("Error al aprobar");
      } finally {
        setAccionEnCurso(false);
        setAprobandoRec(null);
      }
    }

    async function ejecutarRechazarReclamo(rec, razon) {
      if (!rec || !rec.iglesia_id || !rec.uid) return;
      setAccionEnCurso(true);
      try {
        const auth = firebase.auth ? firebase.auth().currentUser : null;
        const uidRev = auth && auth.uid;
        if (!uidRev) throw new Error("Sin sesión.");
        await window.rechazarReclamo(rec.iglesia_id, rec.uid, uidRev, razon || "");
        mostrarToast("Reclamo rechazado");
      } catch (e) {
        console.warn("[SuperAdmin] rechazarReclamo falló:", e);
        mostrarToast("Error al rechazar");
      } finally {
        setAccionEnCurso(false);
        setRechazandoRec(null);
      }
    }

    function renderTabReclamos() {
      if (!reclamos || reclamos.length === 0) {
        return renderEmpty(
          "Sin reclamos pendientes",
          "Cuando un pastor reclame una iglesia no reclamada, la solicitud aparecerá aquí para revisión."
        );
      }
      return (
        <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
          {reclamos.map(function (rec) {
            return (
              <div
                key={rec.id}
                style={{
                  background: bgCard, borderRadius: 14,
                  boxShadow: shadowCard,
                  padding: 14,
                }}
              >
                <div style={{ display: "flex", alignItems: "flex-start", gap: 10, marginBottom: 10 }}>
                  <div style={{
                    width: 40, height: 40, borderRadius: 10,
                    background: BRAND + "15", color: BRAND,
                    display: "flex", alignItems: "center", justifyContent: "center",
                    fontSize: 20, flexShrink: 0,
                  }} aria-hidden="true">🏠</div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 14, fontWeight: 900, color: colorTexto, wordBreak: "break-word" }}>
                      {rec.iglesia_nombre || rec.iglesia_id}
                    </div>
                    <div style={{ fontSize: 12, color: colorSecundario, marginTop: 2 }}>
                      Reclamada por <strong>{rec.nombre_pastor || rec.email_pastor || rec.uid}</strong>
                    </div>
                    {rec.email_pastor && (
                      <div style={{ fontSize: 11, color: colorSecundario, marginTop: 1 }}>
                        ✉️ {rec.email_pastor}
                      </div>
                    )}
                    {rec.telefono_contacto && (
                      <div style={{ fontSize: 11, color: colorSecundario, marginTop: 1 }}>
                        📞 {rec.telefono_contacto}
                      </div>
                    )}
                  </div>
                </div>
                {rec.descripcion && (
                  <div style={{
                    fontSize: 12, color: colorTexto,
                    lineHeight: 1.5, marginBottom: 8,
                    padding: "8px 10px",
                    borderRadius: 8,
                    background: dark ? "#0F0F10" : "#F9FAFB",
                  }}>
                    {rec.descripcion}
                  </div>
                )}
                {rec.direccion_texto && (
                  <div style={{ fontSize: 11, color: colorSecundario, marginBottom: 4 }}>
                    📍 {rec.direccion_texto}
                  </div>
                )}
                {rec.whatsapp && (
                  <div style={{ fontSize: 11, color: colorSecundario, marginBottom: 4 }}>
                    💬 WhatsApp iglesia: {rec.whatsapp}
                  </div>
                )}
                {rec.notas && (
                  <div style={{ fontSize: 11, color: colorSecundario, marginBottom: 8 }}>
                    Notas: {rec.notas}
                  </div>
                )}

                <div style={{ display: "flex", gap: 8, marginTop: 10 }}>
                  <button
                    type="button"
                    onClick={function () { setAprobandoRec(rec); }}
                    style={{
                      flex: 1, padding: "8px 12px", borderRadius: 999,
                      border: "none",
                      background: GREEN, color: "#FFFFFF",
                      fontWeight: 900, fontSize: 12,
                      cursor: "pointer", fontFamily: "inherit",
                    }}
                  >
                    Aprobar
                  </button>
                  <button
                    type="button"
                    onClick={function () { setRechazandoRec(rec); }}
                    style={{
                      flex: 1, padding: "8px 12px", borderRadius: 999,
                      border: "1px solid " + DANGER,
                      background: "transparent",
                      color: DANGER,
                      fontWeight: 900, fontSize: 12,
                      cursor: "pointer", fontFamily: "inherit",
                    }}
                  >
                    Rechazar
                  </button>
                </div>
              </div>
            );
          })}
        </div>
      );
    }

    function renderTabInvitaciones() {
      const lista = invitacionesTodas;
      const tiposGenerar = [
        { id: "pastor",  label: "Pastor",  emoji: "🦯", color: "#6B2FBF" },
        { id: "miembro", label: "Miembro", emoji: "🐑", color: BRAND },
        { id: "amigo",   label: "Amigo",   emoji: "🤝", color: "#00796B" },
      ];
      return (
        <div>
          <div style={{
            fontSize: 11, fontWeight: 800, color: colorSecundario,
            textTransform: "uppercase", letterSpacing: 0.6,
            marginBottom: 8,
          }}>Generar enlace</div>

          <div style={{ display: "flex", gap: 8, marginBottom: 16 }}>
            {tiposGenerar.map(function (t) {
              return (
                <button
                  key={t.id}
                  type="button"
                  onClick={function () { setModalTipo(t.id); }}
                  className="super-press"
                  style={{
                    flex: 1, height: 52,
                    border: "1px solid " + t.color, borderRadius: 12,
                    background: bgCard, color: t.color,
                    fontSize: 14, fontWeight: 800, cursor: "pointer",
                    display: "flex", flexDirection: "column",
                    alignItems: "center", justifyContent: "center", gap: 2,
                  }}
                >
                  <span aria-hidden="true" style={{ fontSize: 18, lineHeight: 1 }}>{t.emoji}</span>
                  <span style={{ lineHeight: 1 }}>{t.label}</span>
                </button>
              );
            })}
          </div>

          {lista.length === 0
            ? renderEmpty("Sin invitaciones", "Aún no se han generado enlaces.")
            : (
              <div style={{ background: bgCard, borderRadius: 14, boxShadow: shadowCard }}>
                {lista.map(function (inv, idx) {
                  return renderItemInvitacion(inv, idx, lista.length);
                })}
              </div>
            )
          }
        </div>
      );
    }

    function tipoBadge(tipo) {
      if (tipo === "pastor")  return { bg: "#F0E6FC", fg: "#6B2FBF", label: "Pastor" };
      if (tipo === "miembro") return { bg: "#E8EEFC", fg: BRAND,     label: "Miembro" };
      if (tipo === "rol")     return { bg: "#FFF4CC", fg: "#8A6700", label: "Rol" };
      if (tipo === "amigo")   return { bg: "#E0F2F1", fg: "#00796B", label: "Amigo" };
      return { bg: dark ? "#1F2937" : "#F0F0F0", fg: colorSecundario, label: String(tipo || "—") };
    }

    function renderItemInvitacion(inv, idx, total) {
      const expiraEn = typeof inv.expira_en === "number" ? inv.expira_en : null;
      const msRestantes = expiraEn == null ? null : (expiraEn - ahora);
      const pill = pillTiempo(msRestantes, expiraEn);
      const usada = !!inv.usado;
      const urlCompleta = PROD_ORIGIN + "/i/" + inv.codigo;
      const tb = tipoBadge(inv.tipo);
      const tituloLinea = inv.iglesia_nombre
        ? inv.iglesia_nombre
        : (inv.destinatario_nombre || "Enlace de " + tb.label.toLowerCase());

      return (
        <div
          key={inv.codigo}
          style={{
            padding: "14px",
            borderBottom: idx < total - 1 ? "1px solid " + colorBorde : "none",
          }}
        >
          <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 8 }}>
            <div style={{
              fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",
              fontSize: 18, fontWeight: 800, letterSpacing: 2,
              color: colorTexto, background: bgMono,
              padding: "6px 10px", borderRadius: 8,
            }}>{formatoCodigo(inv.codigo)}</div>

            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 13, fontWeight: 700, color: colorTexto, wordBreak: "break-word" }}>
                {tituloLinea}
              </div>
              <div style={{ fontSize: 11, color: colorSecundario }}>por {inv.creado_por_nombre || "—"}</div>
            </div>
          </div>

          <div style={{ display: "flex", flexWrap: "wrap", gap: 6, marginBottom: 10 }}>
            <span style={badgePill(tb.bg, tb.fg)}>{tb.label}</span>
            <span style={badgePill(pill.bg, pill.fg)}>
              {expiraEn == null ? "∞ Sin expiración" : "⏱ " + pill.label}
            </span>
            <span style={badgePill(usada ? "#F3E3E3" : "#E6F6D5", usada ? "#B32020" : "#2E7D13")}>
              {usada ? "Usada" : "Activa"}
            </span>
            {inv.destinatario_nombre && (
              <span style={badgePill("#E8EEFC", BRAND)}>{inv.destinatario_nombre}</span>
            )}
          </div>

          <div style={{ display: "flex", gap: 6 }}>
            <button
              type="button"
              onClick={function () {
                const ok = compartirWhatsApp("Te invito a CultoRD", urlCompleta);
                mostrarToast(ok ? "Abriendo WhatsApp..." : "No pudimos abrir WhatsApp");
              }}
              className="super-press"
              style={btnMini("#E6F6D5", "#2E7D13")}
            >💬 WhatsApp</button>

            <button
              type="button"
              onClick={async function () {
                const r = await compartirLink("Invitación CultoRD", "Te invité a CultoRD", urlCompleta);
                if (r === "nativo") mostrarToast("Compartiendo...");
                else if (r === "copiado") mostrarToast("Copiado ✓");
                else if (r === "error") mostrarToast("No pudimos compartir");
              }}
              className="super-press"
              style={btnMini(dark ? "#1F2937" : "#F0F0F0", dark ? "#F0F0F0" : INK)}
            >🔗 Compartir</button>

            <button
              type="button"
              onClick={async function (e) {
                const ok = await copiarAlClipboard(urlCompleta);
                if (ok) {
                  try { e.currentTarget.classList.add("super-bounce"); } catch (_) {}
                  mostrarToast("Copiado ✓");
                  setTimeout(function () {
                    try { if (e.currentTarget) e.currentTarget.classList.remove("super-bounce"); } catch (_) {}
                  }, 340);
                } else {
                  mostrarToast("No pudimos copiar");
                }
              }}
              className="super-press"
              style={btnMini(dark ? "#1F2937" : "#F0F0F0", dark ? "#F0F0F0" : INK)}
            >📋 Copiar</button>

            <button
              type="button"
              onClick={function () { setEliminandoInv(inv); }}
              className="super-press"
              aria-label="Eliminar invitación"
              style={btnMini("#FFE4E4", "#B32020")}
            >🗑</button>
          </div>
        </div>
      );
    }

    function renderEmpty(titulo, descripcion) {
      return (
        <div style={{
          background: bgCard, borderRadius: 14, padding: "32px 18px",
          textAlign: "center", color: colorSecundario, boxShadow: shadowCard,
        }}>
          <div style={{ fontSize: 34, marginBottom: 8 }}>🗂</div>
          <div style={{ fontSize: 15, fontWeight: 800, color: colorTexto, marginBottom: 4 }}>{titulo}</div>
          <div style={{ fontSize: 13 }}>{descripcion}</div>
        </div>
      );
    }
  }

  function badgePill(bg, fg) {
    return {
      display: "inline-block",
      background: bg, color: fg,
      fontSize: 11, fontWeight: 800,
      padding: "4px 10px", borderRadius: 999,
    };
  }

  function btnMini(bg, fg) {
    return {
      flex: 1, height: 36,
      border: "none", borderRadius: 10,
      background: bg, color: fg,
      fontSize: 12, fontWeight: 800, cursor: "pointer",
    };
  }

  // ---------- Modal generar invitación (unificado para pastor/miembro/amigo) ----------

  function textosPorTipo(tipo) {
    if (tipo === "miembro") {
      return {
        titulo: "Nuevo enlace de Miembro",
        subtitulo: "Genera un enlace para que un hermano se afilie a una iglesia.",
        shareTitulo: "Invitación a unirte a una iglesia en CultoRD",
      };
    }
    if (tipo === "amigo") {
      return {
        titulo: "Nuevo enlace de Amigo",
        subtitulo: "Genera un enlace para invitar a un amigo a conocer la comunidad evangélica en CultoRD.",
        shareTitulo: "Te invité a CultoRD",
      };
    }
    return {
      titulo: "Nuevo enlace de Pastor",
      subtitulo: "Genera un enlace para que un pastor reclame su iglesia.",
      shareTitulo: "Invitación a reclamar tu iglesia en CultoRD",
    };
  }

  function ModalGenerarInvitacion({ tipo, user, onCerrar, onCopiar, onCompartir, onToast, iglesiaId, iglesiaNombreForced }) {
    const { dark } = useTheme();
    const colorTexto = dark ? "#F0F0F0" : INK;
    const colorSecundario = dark ? "#9CA3AF" : MUTED;
    const colorBorde = dark ? "#2A2A2A" : "#DDD";
    const bgSheet = dark ? "#1A1A1A" : "#FFFFFF";
    const bgInput = dark ? "#141415" : "#FFFFFF";
    const bgMono = dark ? "#1F2937" : "#F4F6FB";
    const bgHandle = dark ? "#2A2A2A" : "#E5E5E5";
    const bgChipForced = dark ? "#1F2937" : "#EEF2FF";

    // Modo "forzado": el llamador fija la iglesia (caso pastor).
    // En ese modo ocultamos el input de iglesia y usamos los valores dados.
    const iglesiaForzada = !!(iglesiaId && iglesiaNombreForced);

    const [vista, setVista] = useState("form"); // form | exito
    const [nombre, setNombre] = useState("");
    const [iglesiaNombre, setIglesiaNombre] = useState("");
    const [expiracionId, setExpiracionId] = useState("7d");
    const [error, setError] = useState("");
    const [guardando, setGuardando] = useState(false);
    const [generada, setGenerada] = useState(null);

    const textos = textosPorTipo(tipo);

    async function onSubmit() {
      if (guardando) return;
      setError("");
      if (typeof window.crearInvitacion !== "function") {
        setError("No se pudo cargar el módulo de invitaciones.");
        return;
      }
      const opt = OPCIONES_EXPIRACION.find(function (o) { return o.id === expiracionId; }) || OPCIONES_EXPIRACION[3];
      const datos = {
        tipo: tipo,
        destinatario_nombre: nombre.trim(),
        iglesia_id: iglesiaForzada ? iglesiaId : null,
        iglesia_nombre: iglesiaForzada ? iglesiaNombreForced : iglesiaNombre.trim(),
        creado_por: user && user.uid ? user.uid : "",
        creado_por_nombre: user && (user.displayName || user.email) ? (user.displayName || user.email) : "",
        creado_por_email: user && user.email ? user.email : "",
        expira_en: opt.ms == null ? null : (Date.now() + opt.ms),
      };
      setGuardando(true);
      try {
        const inv = await window.crearInvitacion(datos);
        setGenerada(inv);
        setVista("exito");
      } catch (e) {
        console.warn("[SuperAdmin] crearInvitacion falló:", e);
        setError("No pudimos generar el enlace. " + (e && e.message ? e.message : "Intenta de nuevo."));
      } finally {
        setGuardando(false);
      }
    }

    if (typeof document === "undefined") return null;

    const content = (
      <div
        style={{
          position: "fixed", inset: 0, zIndex: 71,
          background: "rgba(0,0,0,0.45)",
          display: "flex", alignItems: "flex-end", justifyContent: "center",
          animation: "superFade 180ms ease-out",
        }}
        onClick={onCerrar}
      >
        <div
          onClick={function (e) { e.stopPropagation(); }}
          style={{
            width: "100%", maxWidth: 430,
            background: bgSheet,
            borderTopLeftRadius: 20, borderTopRightRadius: 20,
            padding: "18px 18px 22px",
            animation: "superSlideUp 260ms cubic-bezier(.2,.9,.3,1.2)",
            maxHeight: "90vh", overflowY: "auto",
          }}
        >
          <div style={{
            width: 44, height: 4, borderRadius: 999,
            background: bgHandle, margin: "0 auto 14px",
          }} aria-hidden="true" />

          {vista === "form" ? renderForm() : renderExito()}
        </div>

        <style>{`
          @keyframes superSlideUp { from { transform: translateY(100%); } to { transform: translateY(0); } }
        `}</style>
      </div>
    );

    return ReactDOM.createPortal(content, document.body);

    function renderForm() {
      const nombreLabel = tipo === "pastor" ? "Nombre del pastor (opcional)"
        : tipo === "miembro" ? "Nombre del miembro (opcional)"
        : "Nombre del amigo (opcional)";

      return (
        <div>
          <div style={{ fontSize: 18, fontWeight: 900, color: colorTexto, marginBottom: 4 }}>{textos.titulo}</div>
          <div style={{ fontSize: 13, color: colorSecundario, marginBottom: 16 }}>{textos.subtitulo}</div>

          {iglesiaForzada && (
            <React.Fragment>
              <label style={labelStyle()}>Iglesia</label>
              <div
                style={{
                  display: "inline-flex",
                  alignItems: "center",
                  gap: 8,
                  padding: "10px 14px",
                  borderRadius: 12,
                  background: bgChipForced,
                  border: "1px solid " + colorBorde,
                  color: colorTexto,
                  fontSize: 14,
                  fontWeight: 800,
                  marginBottom: 4,
                  maxWidth: "100%",
                }}
                title={iglesiaNombreForced}
              >
                <span aria-hidden>🏠</span>
                <span
                  style={{
                    overflow: "hidden",
                    textOverflow: "ellipsis",
                    whiteSpace: "nowrap",
                    maxWidth: 320,
                  }}
                >
                  {iglesiaNombreForced}
                </span>
              </div>
            </React.Fragment>
          )}

          <label style={labelStyle()}>{nombreLabel}</label>
          <input
            type="text"
            value={nombre}
            onChange={function (e) { setNombre(e.target.value); }}
            placeholder="Nombre o grupo"
            style={inputStyle()}
          />

          {!iglesiaForzada && (
            <React.Fragment>
              <label style={labelStyle()}>Iglesia (opcional)</label>
              <input
                type="text"
                value={iglesiaNombre}
                onChange={function (e) { setIglesiaNombre(e.target.value); }}
                placeholder="Nombre de la iglesia"
                style={inputStyle()}
              />
            </React.Fragment>
          )}

          <label style={labelStyle()}>Expiración</label>
          <div style={{ display: "flex", flexWrap: "wrap", gap: 6, marginBottom: 14 }}>
            {OPCIONES_EXPIRACION.map(function (o) {
              const active = expiracionId === o.id;
              return (
                <button
                  key={o.id}
                  type="button"
                  onClick={function () { setExpiracionId(o.id); }}
                  style={{
                    border: "1px solid " + (active ? BRAND : colorBorde),
                    background: active ? BRAND : bgInput,
                    color: active ? "#FFFFFF" : colorTexto,
                    fontSize: 13, fontWeight: 700,
                    padding: "8px 12px", borderRadius: 999, cursor: "pointer",
                    transition: "background 120ms, border 120ms, color 120ms",
                  }}
                >{o.label}</button>
              );
            })}
          </div>

          {error && <div style={{ fontSize: 13, color: DANGER, fontWeight: 700, marginBottom: 10 }}>{error}</div>}

          <div style={{ display: "flex", gap: 8 }}>
            <button
              type="button"
              onClick={onCerrar}
              disabled={guardando}
              className="super-press"
              style={{
                flex: 1, height: 50, border: "1px solid " + colorBorde, background: bgInput, color: colorTexto,
                fontSize: 15, fontWeight: 800, borderRadius: 12,
                cursor: guardando ? "default" : "pointer",
                opacity: guardando ? 0.6 : 1,
              }}
            >Cancelar</button>
            <button
              type="button"
              onClick={onSubmit}
              disabled={guardando}
              className="super-press"
              style={{
                flex: 2, height: 50, border: "none",
                background: GREEN, color: "#FFFFFF",
                fontSize: 16, fontWeight: 800, borderRadius: 12,
                cursor: guardando ? "default" : "pointer",
                boxShadow: "0 4px 0 " + GREEN_SHADOW,
                opacity: guardando ? 0.85 : 1,
              }}
            >{guardando ? "Generando..." : "Generar"}</button>
          </div>
        </div>
      );
    }

    function renderExito() {
      if (!generada) return null;
      const urlCompleta = PROD_ORIGIN + "/i/" + generada.codigo;
      const opt = OPCIONES_EXPIRACION.find(function (o) { return o.id === expiracionId; }) || OPCIONES_EXPIRACION[3];

      return (
        <div style={{ textAlign: "center" }}>
          <div style={{ fontSize: 48, lineHeight: 1, marginBottom: 8 }} aria-hidden="true">✅</div>
          <div style={{ fontSize: 18, fontWeight: 900, color: colorTexto, marginBottom: 4 }}>¡Enlace generado!</div>
          <div style={{ fontSize: 13, color: colorSecundario, marginBottom: 18 }}>
            {generada.destinatario_nombre
              ? <React.Fragment>Para <span style={{ fontWeight: 700, color: colorTexto }}>{generada.destinatario_nombre}</span>.<br /></React.Fragment>
              : null}
            Expira en {opt.label.toLowerCase()}.
          </div>

          <div style={{
            fontSize: 13, color: BRAND, fontWeight: 700,
            wordBreak: "break-all", background: bgMono,
            padding: "12px 14px", borderRadius: 12, marginBottom: 16,
          }}>{urlCompleta}</div>

          <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
            <button
              type="button"
              onClick={function () {
                const ok = compartirWhatsApp(textos.shareTitulo, urlCompleta);
                onToast && onToast(ok ? "Abriendo WhatsApp..." : "No pudimos abrir WhatsApp");
              }}
              className="super-press"
              style={{
                height: 52, border: "none", borderRadius: 12,
                background: "#25D366", color: "#FFFFFF",
                fontSize: 15, fontWeight: 800, cursor: "pointer",
                boxShadow: "0 4px 0 #128C7E",
              }}
            >💬 Enviar por WhatsApp</button>

            <button
              type="button"
              onClick={async function () {
                const r = await onCompartir("Invitación CultoRD",
                  textos.shareTitulo,
                  urlCompleta);
                if (r === "nativo") onToast && onToast("Compartiendo...");
                else if (r === "copiado") onToast && onToast("Copiado ✓");
                else if (r === "error") onToast && onToast("No pudimos compartir");
              }}
              className="super-press"
              style={{
                height: 48, border: "none", borderRadius: 12,
                background: BRAND, color: "#FFFFFF",
                fontSize: 14, fontWeight: 800, cursor: "pointer",
                boxShadow: "0 3px 0 " + BRAND_DARK,
              }}
            >🔗 Compartir en otra red</button>

            <button
              type="button"
              onClick={async function (e) {
                const ok = await onCopiar(urlCompleta);
                if (ok) {
                  try { e.currentTarget.classList.add("super-bounce"); } catch (_) {}
                  onToast && onToast("Copiado ✓");
                  setTimeout(function () {
                    try { if (e.currentTarget) e.currentTarget.classList.remove("super-bounce"); } catch (_) {}
                  }, 340);
                } else {
                  onToast && onToast("No pudimos copiar");
                }
              }}
              className="super-press"
              style={{
                height: 44, border: "1px solid " + colorBorde, borderRadius: 12,
                background: bgInput, color: colorTexto,
                fontSize: 14, fontWeight: 800, cursor: "pointer",
              }}
            >📋 Copiar enlace</button>

            <button
              type="button"
              onClick={onCerrar}
              className="super-press"
              style={{
                height: 40, border: "none", borderRadius: 12,
                background: "transparent", color: colorSecundario,
                fontSize: 14, fontWeight: 700, cursor: "pointer",
              }}
            >Cerrar</button>
          </div>
        </div>
      );
    }

    function labelStyle() {
      return {
        display: "block", fontSize: 12, fontWeight: 800, color: colorTexto,
        textTransform: "uppercase", letterSpacing: 0.3,
        margin: "10px 0 6px",
      };
    }
    function inputStyle() {
      return {
        width: "100%", height: 48,
        border: "1px solid " + colorBorde, borderRadius: 12,
        padding: "0 14px", fontSize: 15, color: colorTexto,
        outline: "none", background: bgInput,
        boxSizing: "border-box",
      };
    }
  }

  // ---------- Item de solicitud pendiente ----------

  function haceTiempo(ms) {
    if (typeof ms !== "number") return "";
    const diff = Date.now() - ms;
    if (diff < 60 * 1000) return "hace instantes";
    if (diff < 60 * 60 * 1000) {
      const m = Math.floor(diff / 60000);
      return "hace " + m + " min";
    }
    if (diff < 24 * 60 * 60 * 1000) {
      const h = Math.floor(diff / 3600000);
      return "hace " + h + " h";
    }
    const d = Math.floor(diff / 86400000);
    return "hace " + d + (d === 1 ? " día" : " días");
  }

  function useUserPerfil(uid) {
    const { useState, useEffect } = React;
    const [perfil, setPerfil] = useState(null);
    useEffect(function () {
      if (!uid || !window.db) return;
      let cancelled = false;
      window.db.ref("users/" + uid + "/perfil").once("value")
        .then(function (snap) { if (!cancelled) setPerfil(snap.val() || {}); })
        .catch(function () { /* noop, seguimos con solo datos de la solicitud */ });
      return function () { cancelled = true; };
    }, [uid]);
    return perfil;
  }

  function ItemSolicitud({ sol, onAprobar, onRechazar }) {
    const BRAND = "#2563EB";
    const INK = "#3C3C3C";
    const MUTED = "#777";
    const GREEN = "#58CC02";
    const GREEN_SHADOW = "#46A302";
    const DANGER = "#FF4B4B";
    const DIVIDER = "#EEE";

    const { dark } = useTheme();
    const colorTexto = dark ? "#F0F0F0" : INK;
    const colorSecundario = dark ? "#9CA3AF" : MUTED;
    const colorBorde = dark ? "#2A2A2A" : DIVIDER;
    const bgCard = dark ? "#1A1A1A" : "#FFFFFF";
    const bgInfoBox = dark ? "#141415" : "#F9FAFB";

    const perfil = useUserPerfil(sol && sol.uid);
    const email = (perfil && perfil.email) || "";
    const fotoUrl = (perfil && perfil.foto_url) || "";
    const nombre = sol.nombre_completo || (perfil && perfil.nombre) || "Sin nombre";
    const inicial = String(nombre).trim().charAt(0).toUpperCase() || "?";

    const telDigits = String(sol.telefono || "").replace(/\D+/g, "");
    const whatsappUrl = telDigits.length >= 7
      ? "https://wa.me/" + (telDigits.length === 10 ? "1" + telDigits : telDigits)
      : "";

    return (
      <div style={{
        background: bgCard, borderRadius: 14,
        padding: 14, boxShadow: "0 1px 0 " + colorBorde,
      }}>
        <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 10 }}>
          {fotoUrl ? (
            <img
              src={fotoUrl}
              alt=""
              width={44}
              height={44}
              style={{ width: 44, height: 44, borderRadius: 22, objectFit: "cover", flexShrink: 0 }}
            />
          ) : (
            <div style={{
              width: 44, height: 44, borderRadius: 22,
              background: BRAND + "1A", color: BRAND,
              display: "flex", alignItems: "center", justifyContent: "center",
              fontSize: 18, fontWeight: 900, flexShrink: 0,
            }} aria-hidden>{inicial}</div>
          )}
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 15, fontWeight: 900, color: colorTexto, wordBreak: "break-word" }}>
              {nombre}
            </div>
            {email ? (
              <div style={{ fontSize: 12, color: colorSecundario, wordBreak: "break-all" }}>{email}</div>
            ) : null}
            <div style={{ fontSize: 11, color: colorSecundario, marginTop: 2 }}>
              {haceTiempo(sol.creado_en)}
            </div>
          </div>
        </div>

        <div style={{
          background: bgInfoBox, borderRadius: 10, padding: "10px 12px",
          display: "flex", flexDirection: "column", gap: 4, marginBottom: 10,
        }}>
          <FieldRow label="Iglesia" value={sol.iglesia_nombre} dark={dark} />
          <FieldRow label="Ciudad" value={sol.ciudad} dark={dark} />
          <FieldRow label="Miembros" value={sol.cantidad_miembros != null ? String(sol.cantidad_miembros) : ""} dark={dark} />
          <FieldRow
            label="Años pastoreando"
            value={sol.anos_pastoreando != null ? String(sol.anos_pastoreando) : ""}
            dark={dark}
          />
          <FieldRow label="Teléfono" value={sol.telefono} dark={dark} />
          {sol.comentario ? (
            <div style={{ marginTop: 4 }}>
              <div style={{ fontSize: 10, fontWeight: 800, color: colorSecundario, textTransform: "uppercase", letterSpacing: 0.4 }}>
                Comentario
              </div>
              <div style={{ fontSize: 13, color: colorTexto, lineHeight: 1.45, whiteSpace: "pre-wrap" }}>
                {sol.comentario}
              </div>
            </div>
          ) : null}
        </div>

        {whatsappUrl ? (
          <a
            href={whatsappUrl}
            target="_blank"
            rel="noopener noreferrer"
            style={{
              display: "inline-flex", alignItems: "center", gap: 6,
              fontSize: 13, fontWeight: 900,
              color: "#128C7E", textDecoration: "none",
              padding: "6px 10px", borderRadius: 8,
              background: "#E6F6D5", marginBottom: 10,
            }}
          >💬 WhatsApp</a>
        ) : null}

        <div style={{ display: "flex", gap: 8 }}>
          <button
            type="button"
            onClick={onAprobar}
            style={{
              flex: 1, minHeight: 42,
              border: "none", borderRadius: 12,
              background: GREEN, color: "#FFFFFF",
              fontSize: 14, fontWeight: 900, cursor: "pointer",
              boxShadow: "0 3px 0 " + GREEN_SHADOW,
              fontFamily: "inherit",
            }}
          >✓ Aprobar</button>
          <button
            type="button"
            onClick={onRechazar}
            style={{
              flex: 1, minHeight: 42,
              border: "1.5px solid " + DANGER, borderRadius: 12,
              background: bgCard, color: DANGER,
              fontSize: 14, fontWeight: 900, cursor: "pointer",
              fontFamily: "inherit",
            }}
          >✗ Rechazar</button>
        </div>
      </div>
    );
  }

  function FieldRow({ label, value, dark }) {
    if (!value) return null;
    const labelColor = dark ? "#9CA3AF" : "#777";
    const valueColor = dark ? "#F0F0F0" : "#3C3C3C";
    return (
      <div style={{ display: "flex", gap: 8, fontSize: 13 }}>
        <div style={{ width: 110, flexShrink: 0, color: labelColor, fontWeight: 700 }}>{label}</div>
        <div style={{ flex: 1, color: valueColor, fontWeight: 700, wordBreak: "break-word" }}>{value}</div>
      </div>
    );
  }

  // ---------- Modal para rechazar (con textarea obligatoria) ----------

  function RechazarSolicitudModal({ sol, cargando, onCancelar, onConfirmar }) {
    const { useState, useEffect, useRef } = React;
    const { dark } = useTheme();
    const colorTexto = dark ? "#F0F0F0" : "#2A2A2A";
    const colorSecundario = dark ? "#9CA3AF" : "#777";
    const colorBorde = dark ? "#2A2A2A" : "#E5E7EB";
    const colorBordeBoton = dark ? "#2A2A2A" : "#DDD";
    const bgCard = dark ? "#1A1A1A" : "#FFFFFF";
    const bgInput = dark ? "#141415" : "#F9FAFB";
    const bgErrorBox = dark ? "#3F1D1D" : "#FEE2E2";
    const [razon, setRazon] = useState("");
    const [error, setError] = useState("");
    const textareaRef = useRef(null);

    useEffect(function () {
      if (textareaRef.current) {
        try { textareaRef.current.focus(); } catch (_) {}
      }
      const onKey = function (e) { if (e.key === "Escape" && !cargando) onCancelar && onCancelar(); };
      document.addEventListener("keydown", onKey);
      return function () { document.removeEventListener("keydown", onKey); };
    }, [cargando, onCancelar]);

    if (typeof document === "undefined") return null;

    function submit() {
      const texto = razon.trim();
      if (texto.length < 3) {
        setError("Escriba una razón (mínimo 3 caracteres).");
        return;
      }
      setError("");
      onConfirmar && onConfirmar(texto);
    }

    const content = (
      <div
        style={{
          position: "fixed", inset: 0, zIndex: 90,
          background: "rgba(15, 23, 42, 0.55)",
          display: "flex", alignItems: "center", justifyContent: "center",
          padding: 16,
        }}
        onClick={function () { if (!cargando) onCancelar && onCancelar(); }}
      >
        <div
          onClick={function (e) { e.stopPropagation(); }}
          style={{
            width: "100%", maxWidth: 380,
            background: bgCard, borderRadius: 20,
            padding: "22px 20px",
            boxShadow: "0 20px 60px rgba(0,0,0,0.25)",
          }}
        >
          <h2 style={{ margin: 0, fontSize: 18, fontWeight: 900, color: colorTexto }}>
            Rechazar solicitud
          </h2>
          <p style={{ margin: "8px 0 14px", fontSize: 13, color: colorSecundario, fontWeight: 600, lineHeight: 1.5 }}>
            Explique brevemente por qué rechaza la solicitud de{" "}
            <strong style={{ color: colorTexto }}>{(sol && sol.nombre_completo) || "este usuario"}</strong>.
            El usuario verá este motivo.
          </p>

          <textarea
            ref={textareaRef}
            value={razon}
            onChange={function (e) { setError(""); setRazon(e.target.value.slice(0, 500)); }}
            placeholder="Ej. La información no pudo ser verificada..."
            rows={4}
            maxLength={500}
            disabled={cargando}
            style={{
              width: "100%",
              fontSize: 14, color: colorTexto,
              background: bgInput,
              border: "2px solid " + (error ? "#DC2626" : colorBorde),
              borderRadius: 12,
              padding: "10px 12px",
              outline: "none",
              fontFamily: "inherit",
              boxSizing: "border-box",
              resize: "vertical",
              minHeight: 90,
            }}
          />
          <div style={{ fontSize: 11, color: colorSecundario, fontWeight: 600, marginTop: 4, textAlign: "right" }}>
            {razon.length} / 500
          </div>
          {error ? (
            <div style={{
              fontSize: 12, color: dark ? "#FCA5A5" : "#DC2626", fontWeight: 700,
              background: bgErrorBox, borderRadius: 10, padding: "8px 10px",
              marginTop: 6,
            }}>{error}</div>
          ) : null}

          <div style={{ display: "flex", gap: 8, marginTop: 14 }}>
            <button
              type="button"
              onClick={onCancelar}
              disabled={cargando}
              style={{
                flex: 1, minHeight: 46, border: "1px solid " + colorBordeBoton, borderRadius: 12,
                background: bgCard, color: colorTexto,
                fontSize: 14, fontWeight: 800,
                cursor: cargando ? "default" : "pointer",
                opacity: cargando ? 0.6 : 1,
                fontFamily: "inherit",
              }}
            >Cancelar</button>
            <button
              type="button"
              onClick={submit}
              disabled={cargando}
              style={{
                flex: 1, minHeight: 46, border: "none", borderRadius: 12,
                background: "#DC2626", color: "#FFFFFF",
                fontSize: 14, fontWeight: 900,
                cursor: cargando ? "default" : "pointer",
                boxShadow: "0 3px 0 #991B1B",
                opacity: cargando ? 0.8 : 1,
                fontFamily: "inherit",
              }}
            >{cargando ? "Rechazando..." : "Rechazar"}</button>
          </div>
        </div>
      </div>
    );

    return ReactDOM.createPortal(content, document.body);
  }

  window.SuperAdmin = SuperAdmin;
  window.ModalGenerarInvitacion = ModalGenerarInvitacion;
})();
