/* GestionarActividades → window. Pantalla INLINE (no portal) para
   publicar y gestionar actividades puntuales (retiros, vigilias,
   campañas, culto unido, etc.) de una iglesia.

   Permisos internos (la autoridad real está en las reglas RTDB):
     - Pastor dueño (iglesias_admin/{iglesiaId}=true) → acceso total.
     - Rol actividades_espirituales activo y vigente → acceso total.
     - Superadmin → acceso total.

   Props:
     - iglesiaId: id de la iglesia (string)
     - iglesia:   { id, nombre } (usado solo para el header)
     - onCerrar:  () => void

   El modal PublicarActividadModal está definido en este mismo archivo
   y vive como portal (zIndex 76) — es un diálogo sobre la pantalla,
   no una vista de navegación. */
(function () {
  const { useState, useEffect, useMemo } = React;
  const { useAuth, useTheme, BackIcon, TIPOS_ACTIVIDAD } = window;

  const BRAND = "#2563EB";
  const BRAND_DARK = "#1E4ED8";
  const GREEN = "#58CC02";
  const GREEN_SHADOW = "#46A302";
  const DANGER = "#DC2626";
  const INK = "#3C3C3C";
  const MUTED = "#777";

  // ----- Helpers fecha -----

  const DIAS_SEMANA = ["Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb"];
  const MESES_ABREV = ["ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic"];

  function fechaAYYYYMMDD(ms) {
    if (typeof ms !== "number") return "";
    const d = new Date(ms);
    const y = d.getFullYear();
    const m = String(d.getMonth() + 1).padStart(2, "0");
    const day = String(d.getDate()).padStart(2, "0");
    return y + "-" + m + "-" + day;
  }

  function yyyymmddAMs(s) {
    if (typeof s !== "string" || !/^\d{4}-\d{2}-\d{2}$/.test(s)) return null;
    const [y, m, d] = s.split("-").map(Number);
    return new Date(y, m - 1, d, 0, 0, 0, 0).getTime();
  }

  function fmtFechaCorta(ms) {
    if (typeof ms !== "number") return "";
    const d = new Date(ms);
    return DIAS_SEMANA[d.getDay()] + " " + d.getDate() + " " + MESES_ABREV[d.getMonth()];
  }

  function fmtRangoFechas(ini, fin) {
    if (typeof ini !== "number") return "";
    const a = new Date(ini);
    const b = typeof fin === "number" ? new Date(fin) : a;
    const mismoDia = a.getFullYear() === b.getFullYear()
      && a.getMonth() === b.getMonth()
      && a.getDate() === b.getDate();
    if (mismoDia) return fmtFechaCorta(ini);
    return fmtFechaCorta(ini) + " → " + fmtFechaCorta(fin);
  }

  function fmtHora12(hhmm) {
    if (!hhmm || !/^\d{2}:\d{2}$/.test(hhmm)) return hhmm || "";
    const [h, m] = hhmm.split(":").map(Number);
    const period = h >= 12 ? "PM" : "AM";
    const hr = h % 12 || 12;
    return hr + ":" + String(m).padStart(2, "0") + " " + period;
  }

  // ====================================================================
  //  Modal: Publicar / Editar actividad
  // ====================================================================

  const OPCIONES_TIPO_ORDEN = [
    "culto_unido", "retiro", "vigilia", "campana",
    "conferencia", "ayuno", "bautismo", "santa_cena", "otro",
  ];

  function PublicarActividadModal({ iglesia, actividadEditando, onCerrar, onGuardado }) {
    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 bgHandle = dark ? "#2A2A2A" : "#E5E5E5";
    const bgChipOff = dark ? "#141415" : "#F3F4F6";

    const esEdicion = !!actividadEditando;

    // Estado inicial del formulario.
    const tiposIds = OPCIONES_TIPO_ORDEN.filter(function (id) { return !!TIPOS_ACTIVIDAD[id]; });
    const hoyMs = (function () {
      const d = new Date();
      return new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();
    })();

    const [titulo, setTitulo]               = useState(actividadEditando ? (actividadEditando.titulo || "") : "");
    const [tipo, setTipo]                   = useState(actividadEditando ? (actividadEditando.tipo || "culto_unido") : "culto_unido");
    const [tipoOtro, setTipoOtro]           = useState(actividadEditando ? (actividadEditando.tipo_otro || "") : "");
    const [fechaInicio, setFechaInicio]     = useState(actividadEditando && actividadEditando.fecha_inicio ? fechaAYYYYMMDD(actividadEditando.fecha_inicio) : fechaAYYYYMMDD(hoyMs));
    const [fechaFin, setFechaFin]           = useState(actividadEditando && actividadEditando.fecha_fin ? fechaAYYYYMMDD(actividadEditando.fecha_fin) : fechaAYYYYMMDD(hoyMs));
    const [fechaFinTocada, setFechaFinTocada] = useState(!!(actividadEditando && actividadEditando.fecha_fin && actividadEditando.fecha_fin !== actividadEditando.fecha_inicio));
    const [hora, setHora]                   = useState(actividadEditando ? (actividadEditando.hora || "19:00") : "19:00");
    const [ubicacion, setUbicacion]         = useState(actividadEditando ? (actividadEditando.ubicacion || "") : "");
    const [descripcion, setDescripcion]     = useState(actividadEditando ? (actividadEditando.descripcion || "") : "");

    const [archivo, setArchivo]             = useState(null);
    const [preview, setPreview]             = useState(actividadEditando ? (actividadEditando.imagen_url || "") : "");
    const [errorImg, setErrorImg]           = useState("");
    const [subiendoImg, setSubiendoImg]     = useState(false);
    const [progresoImg, setProgresoImg]     = useState(0);

    const [guardando, setGuardando]         = useState(false);
    const [error, setError]                 = useState("");

    // ESC cierra el modal (si no estamos guardando).
    useEffect(function () {
      const onKey = function (e) {
        if (e.key === "Escape" && !guardando && !subiendoImg) onCerrar && onCerrar();
      };
      document.addEventListener("keydown", onKey);
      return function () { document.removeEventListener("keydown", onKey); };
    }, [guardando, subiendoImg, onCerrar]);

    // Si el user edita fecha_inicio y aún no tocó fecha_fin, sincronizar.
    useEffect(function () {
      if (!fechaFinTocada) setFechaFin(fechaInicio);
      // Si fechaFin quedó antes que fechaInicio, alinear.
      else if (yyyymmddAMs(fechaFin) < yyyymmddAMs(fechaInicio)) setFechaFin(fechaInicio);
    }, [fechaInicio]); // eslint-disable-line

    // Preview del archivo local (revoca URL al cambiar).
    useEffect(function () {
      if (!archivo) return;
      const url = URL.createObjectURL(archivo);
      setPreview(url);
      return function () { URL.revokeObjectURL(url); };
    }, [archivo]);

    function handleFile(e) {
      setErrorImg("");
      const f = e.target.files && e.target.files[0];
      if (!f) return;
      if (!/^image\//.test(f.type)) {
        setErrorImg("El archivo debe ser una imagen.");
        return;
      }
      if (f.size > 10 * 1024 * 1024) {
        setErrorImg("La imagen supera 10 MB. Comprímala antes de subirla.");
        return;
      }
      setArchivo(f);
    }

    function tituloValido() {
      const t = String(titulo || "").trim();
      return t.length >= 3 && t.length <= 120;
    }
    function tipoOtroValido() {
      if (tipo !== "otro") return true;
      const t = String(tipoOtro || "").trim();
      return t.length >= 2 && t.length <= 60;
    }
    function horaValida() {
      return /^[0-2][0-9]:[0-5][0-9]$/.test(String(hora || ""));
    }
    const puedeGuardar = tituloValido() && tipoOtroValido() && horaValida() && !!fechaInicio && !!fechaFin && !guardando;

    async function handleGuardar() {
      if (!puedeGuardar) return;
      setError("");
      setGuardando(true);
      try {
        const fechaInicioMs = yyyymmddAMs(fechaInicio);
        const fechaFinMsRaw = yyyymmddAMs(fechaFin);
        const fechaFinMs = fechaFinMsRaw != null && fechaFinMsRaw >= fechaInicioMs
          ? fechaFinMsRaw
          : fechaInicioMs;

        const datos = {
          titulo: String(titulo).trim(),
          tipo: tipo,
          tipo_otro: tipo === "otro" ? String(tipoOtro).trim() : "",
          fecha_inicio: fechaInicioMs,
          fecha_fin: fechaFinMs,
          hora: hora,
          ubicacion: String(ubicacion || "").trim(),
          descripcion: String(descripcion || "").trim(),
        };

        let actividadId = actividadEditando && actividadEditando.id;

        if (esEdicion) {
          await window.actualizarActividad(iglesia.id, actividadId, datos);
        } else {
          actividadId = await window.crearActividad(iglesia.id, datos);
        }

        // Si hay archivo nuevo, subimos la imagen DESPUÉS de crear/guardar
        // la actividad (mismo patrón que RegistrarIglesia). Si falla, el
        // registro principal igual queda persistido.
        if (archivo && actividadId && typeof window.subirImagenActividad === "function") {
          setSubiendoImg(true);
          try {
            await window.subirImagenActividad(iglesia.id, actividadId, archivo, function (p) {
              setProgresoImg(p);
            });
          } catch (e2) {
            console.warn("[GestionarActividades] subirImagenActividad falló:", e2);
            // No bloqueamos la operación; avisamos pero dejamos pasar.
            setError("Se publicó, pero la imagen no se pudo subir. Puedes editar la actividad para reintentar.");
            setSubiendoImg(false);
            // Callback de guardado de todas formas.
            if (typeof onGuardado === "function") onGuardado(actividadId);
            setGuardando(false);
            return;
          }
          setSubiendoImg(false);
        }

        if (typeof onGuardado === "function") onGuardado(actividadId);
        onCerrar && onCerrar();
      } catch (e) {
        console.warn("[GestionarActividades] guardar falló:", e);
        setError((e && e.message) || "No pudimos guardar la actividad.");
      } finally {
        setGuardando(false);
      }
    }

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

    const content = (
      <div
        style={{
          position: "fixed", inset: 0, zIndex: 76,
          background: "rgba(0,0,0,0.5)",
          display: "flex", alignItems: "flex-end", justifyContent: "center",
          animation: "gactFade 180ms ease-out",
        }}
        onClick={function () { if (!guardando && !subiendoImg) onCerrar && onCerrar(); }}
      >
        <div
          onClick={function (e) { e.stopPropagation(); }}
          style={{
            width: "100%", maxWidth: 430,
            background: bgSheet,
            borderTopLeftRadius: 20, borderTopRightRadius: 20,
            padding: "18px 18px 22px",
            maxHeight: "94vh",
            display: "flex", flexDirection: "column",
            animation: "gactSlideUp 260ms cubic-bezier(.2,.9,.3,1.2)",
          }}
        >
          <div
            style={{
              width: 44, height: 4, borderRadius: 999,
              background: bgHandle, margin: "0 auto 14px",
            }}
            aria-hidden
          />

          <div style={{ overflowY: "auto", WebkitOverflowScrolling: "touch", flex: 1, paddingRight: 2 }}>
            <div style={{ fontSize: 12, fontWeight: 700, color: colorSecundario, textTransform: "uppercase", letterSpacing: 0.4 }}>
              {esEdicion ? "Editar actividad" : "Publicar actividad"}
            </div>
            <div style={{ fontSize: 17, fontWeight: 900, color: colorTexto, lineHeight: 1.2, marginTop: 2, marginBottom: 14 }}>
              {iglesia && iglesia.nombre ? iglesia.nombre : "Actividad"}
            </div>

            {/* Título */}
            <label style={labelStyle(colorTexto)}>Título</label>
            <input
              type="text"
              value={titulo}
              onChange={function (e) { setTitulo(e.target.value); }}
              placeholder="Ej: Retiro juvenil 2026"
              maxLength={120}
              style={inputStyle(colorBorde, bgInput, colorTexto)}
            />

            {/* Tipo (grid 3x3) */}
            <label style={labelStyle(colorTexto)}>Tipo</label>
            <div
              style={{
                display: "grid",
                gridTemplateColumns: "repeat(3, minmax(0, 1fr))",
                gap: 8, marginBottom: 10,
              }}
            >
              {tiposIds.map(function (id) {
                const t = TIPOS_ACTIVIDAD[id];
                const active = tipo === id;
                return (
                  <button
                    key={id}
                    type="button"
                    onClick={function () { setTipo(id); }}
                    style={{
                      display: "flex", flexDirection: "column",
                      alignItems: "center", gap: 4,
                      padding: "10px 6px", borderRadius: 12,
                      border: "1.5px solid " + (active ? BRAND : colorBorde),
                      background: active ? (dark ? "#0B1B3D" : "#EEF2FF") : bgChipOff,
                      color: colorTexto, cursor: "pointer",
                      fontFamily: "inherit",
                    }}
                  >
                    <div style={{ fontSize: 22, lineHeight: 1 }} aria-hidden>{t.emoji}</div>
                    <div
                      style={{
                        fontSize: 10, fontWeight: 800,
                        color: active ? BRAND : colorTexto,
                        textAlign: "center", lineHeight: 1.2,
                      }}
                    >
                      {t.label}
                    </div>
                  </button>
                );
              })}
            </div>

            {tipo === "otro" && (
              <React.Fragment>
                <label style={labelStyle(colorTexto)}>Nombre del tipo</label>
                <input
                  type="text"
                  value={tipoOtro}
                  onChange={function (e) { setTipoOtro(e.target.value); }}
                  placeholder="Ej: Maratón de oración"
                  maxLength={60}
                  style={inputStyle(colorBorde, bgInput, colorTexto)}
                />
              </React.Fragment>
            )}

            {/* Fechas */}
            <label style={labelStyle(colorTexto)}>Fecha</label>
            <div style={{ display: "flex", gap: 8, marginBottom: 10 }}>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 11, fontWeight: 700, color: colorSecundario, marginBottom: 4 }}>
                  Inicio
                </div>
                <input
                  type="date"
                  value={fechaInicio}
                  onChange={function (e) { setFechaInicio(e.target.value); }}
                  style={inputStyle(colorBorde, bgInput, colorTexto)}
                />
              </div>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 11, fontWeight: 700, color: colorSecundario, marginBottom: 4 }}>
                  Fin
                </div>
                <input
                  type="date"
                  value={fechaFin}
                  min={fechaInicio || undefined}
                  onChange={function (e) {
                    setFechaFin(e.target.value);
                    setFechaFinTocada(true);
                  }}
                  style={inputStyle(colorBorde, bgInput, colorTexto)}
                />
              </div>
            </div>

            {/* Hora */}
            <label style={labelStyle(colorTexto)}>Hora</label>
            <input
              type="time"
              value={hora}
              onChange={function (e) { setHora(e.target.value); }}
              style={inputStyle(colorBorde, bgInput, colorTexto)}
            />

            {/* Ubicación */}
            <label style={labelStyle(colorTexto)}>Ubicación (opcional)</label>
            <input
              type="text"
              value={ubicacion}
              onChange={function (e) { setUbicacion(e.target.value); }}
              placeholder="Mismo lugar de la iglesia"
              maxLength={300}
              style={inputStyle(colorBorde, bgInput, colorTexto)}
            />

            {/* Descripción */}
            <label style={labelStyle(colorTexto)}>Descripción (opcional)</label>
            <textarea
              value={descripcion}
              onChange={function (e) { setDescripcion(e.target.value); }}
              placeholder="Detalles, programa, oradores, etc."
              maxLength={1000}
              rows={3}
              style={Object.assign({}, inputStyle(colorBorde, bgInput, colorTexto), {
                height: "auto", minHeight: 72, padding: "12px 14px", resize: "vertical",
              })}
            />

            {/* Flyer */}
            <label style={labelStyle(colorTexto)}>Flyer (vertical, opcional)</label>
            <div style={{ display: "flex", justifyContent: "center", marginBottom: 8 }}>
              <div
                style={{
                  position: "relative",
                  width: 200, height: 267, // 3:4 vertical
                  borderRadius: 14,
                  border: "1.5px dashed " + colorBorde,
                  background: preview ? "#000" : (dark ? "#141415" : "#F3F4F6"),
                  overflow: "hidden",
                  display: "flex", alignItems: "center", justifyContent: "center",
                }}
              >
                {preview ? (
                  <img
                    src={preview}
                    alt="Flyer"
                    referrerPolicy="no-referrer"
                    style={{ width: "100%", height: "100%", objectFit: "cover" }}
                  />
                ) : (
                  <div style={{ textAlign: "center", padding: 12 }}>
                    <div style={{ fontSize: 36, lineHeight: 1, marginBottom: 4 }} aria-hidden>🖼️</div>
                    <div style={{ fontSize: 11, fontWeight: 700, color: colorSecundario }}>
                      Toque aquí para elegir (3:4)
                    </div>
                  </div>
                )}
                <input
                  type="file"
                  accept="image/*"
                  onChange={handleFile}
                  style={{
                    position: "absolute", inset: 0,
                    opacity: 0, cursor: "pointer",
                  }}
                  aria-label="Seleccionar imagen"
                />
                {subiendoImg && (
                  <div
                    style={{
                      position: "absolute", inset: 0,
                      background: "rgba(0,0,0,0.6)",
                      color: "#fff",
                      display: "flex", alignItems: "center", justifyContent: "center",
                      fontSize: 12, fontWeight: 800,
                    }}
                  >
                    Subiendo {progresoImg}%
                  </div>
                )}
              </div>
            </div>
            {errorImg && (
              <div style={{ fontSize: 12, color: DANGER, fontWeight: 700, marginTop: -4, marginBottom: 8 }}>
                {errorImg}
              </div>
            )}

            {error && (
              <div style={{ fontSize: 13, color: DANGER, fontWeight: 700, marginTop: 6, marginBottom: 6 }}>
                {error}
              </div>
            )}
          </div>

          <div style={{ display: "flex", gap: 8, marginTop: 14 }}>
            <button
              type="button"
              onClick={onCerrar}
              disabled={guardando || subiendoImg}
              style={{
                flex: 1, height: 50, border: "1px solid " + colorBorde,
                background: bgInput, color: colorTexto,
                fontSize: 15, fontWeight: 800, borderRadius: 12,
                cursor: (guardando || subiendoImg) ? "default" : "pointer",
                opacity: (guardando || subiendoImg) ? 0.6 : 1,
              }}
            >
              Cancelar
            </button>
            <button
              type="button"
              onClick={handleGuardar}
              disabled={!puedeGuardar}
              style={{
                flex: 2, height: 50, border: "none",
                background: GREEN, color: "#FFFFFF",
                fontSize: 16, fontWeight: 800, borderRadius: 12,
                cursor: puedeGuardar ? "pointer" : "default",
                boxShadow: "0 4px 0 " + GREEN_SHADOW,
                opacity: puedeGuardar ? 1 : 0.6,
              }}
            >
              {guardando
                ? (subiendoImg ? "Subiendo imagen…" : "Guardando…")
                : (esEdicion ? "Guardar cambios" : "Publicar")}
            </button>
          </div>
        </div>

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

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

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

  // ====================================================================
  //  Componente principal: GestionarActividades (inline)
  // ====================================================================

  function GestionarActividades({ iglesiaId, iglesia, onCerrar }) {
    const { user } = (typeof useAuth === "function" ? useAuth() : {}) || {};
    const { dark } = useTheme();

    const colorTexto = dark ? "#F0F0F0" : INK;
    const colorSecundario = dark ? "#9CA3AF" : MUTED;
    const colorBorde = dark ? "#2A2A2A" : "#E5E7EB";
    const bgCard = dark ? "#1A1A1A" : "#FFFFFF";
    const bgPlaceholder = dark ? "#1F2937" : "#EEF2FF";
    const shadowCard = dark ? "0 1px 2px rgba(0,0,0,0.3)" : "0 1px 2px rgba(16,24,40,0.06)";
    const bgBanner = dark ? "#0B1B3D" : "#EFF6FF";
    const colorBanner = dark ? "#93C5FD" : "#1E40AF";
    const bgBadgeTipo = dark ? "#1F2937" : "#EEF2FF";
    const colorBadgeTipo = dark ? "#C7D2FE" : BRAND_DARK;

    // --- Permisos ---
    const perfilUsuario = typeof window.miPerfil === "function" ? window.miPerfil() : null;
    const esSuper = typeof window.esSuperadmin === "function" && user ? window.esSuperadmin(user) : false;
    const esPastorOwner =
      !!(perfilUsuario && perfilUsuario.iglesias_admin && perfilUsuario.iglesias_admin[iglesiaId] === true);

    const [rolesEnIglesia, setRolesEnIglesia] = useState({});
    useEffect(function () {
      if (esPastorOwner || esSuper) { setRolesEnIglesia({}); return; }
      if (!user || !user.uid || !iglesiaId || !window.db) return;
      const ref = window.db.ref("users/" + user.uid + "/roles/" + iglesiaId);
      const handler = function (snap) {
        setRolesEnIglesia(snap && snap.exists() ? (snap.val() || {}) : {});
      };
      ref.on("value", handler, function (err) {
        console.warn("[GestionarActividades] roles denegado:", err && err.code);
        setRolesEnIglesia({});
      });
      return function () { ref.off("value", handler); };
    }, [user && user.uid, iglesiaId, esPastorOwner, esSuper]);

    const tieneRolActividades = rolesEnIglesia.actividades_espirituales === true;
    const puedeGestionar = esPastorOwner || esSuper || tieneRolActividades;

    // --- Datos ---
    const [actividades, setActividades] = useState([]);
    const [cargando, setCargando] = useState(true);
    useEffect(function () {
      if (!iglesiaId || typeof window.suscribirActividadesDeIglesia !== "function") {
        setActividades([]);
        setCargando(false);
        return;
      }
      setCargando(true);
      const unsub = window.suscribirActividadesDeIglesia(iglesiaId, function (arr) {
        setActividades(Array.isArray(arr) ? arr : []);
        setCargando(false);
      });
      return function () { if (typeof unsub === "function") unsub(); };
    }, [iglesiaId]);

    // --- Contadores de asistencia por actividad (mapa { actId: total }) ---
    const [contadores, setContadores] = useState({});
    useEffect(function () {
      if (!iglesiaId || typeof window.suscribirContadoresDeIglesia !== "function") {
        setContadores({});
        return;
      }
      const unsub = window.suscribirContadoresDeIglesia(iglesiaId, function (m) {
        setContadores(m && typeof m === "object" ? m : {});
      });
      return function () { if (typeof unsub === "function") unsub(); };
    }, [iglesiaId]);

    // --- Modal state ---
    const [modalAbierto, setModalAbierto] = useState(false);
    const [actividadEditando, setActividadEditando] = useState(null);
    const [revocarActividad, setRevocarActividad] = useState(null); // actividad a eliminar
    const [eliminandoEnCurso, setEliminandoEnCurso] = useState(false);
    const [toast, setToast] = useState("");
    // Actividad cuya lista de asistentes se está viendo (reemplaza la
    // pantalla actual con ListaAsistentes vía early-return).
    const [viendoAsistentesDe, setViendoAsistentesDe] = useState(null);

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

    function abrirPublicar() {
      setActividadEditando(null);
      setModalAbierto(true);
    }
    function abrirEditar(act) {
      setActividadEditando(act);
      setModalAbierto(true);
    }

    async function ejecutarEliminar() {
      if (!revocarActividad || eliminandoEnCurso) return;
      setEliminandoEnCurso(true);
      try {
        await window.eliminarActividad(iglesiaId, revocarActividad.id);
        mostrarToast("Actividad eliminada");
        setRevocarActividad(null);
      } catch (e) {
        console.warn("[GestionarActividades] eliminar falló:", e);
        mostrarToast("No pudimos eliminar. " + (e && e.message ? e.message : ""));
      } finally {
        setEliminandoEnCurso(false);
      }
    }

    // ESC → cerrar pantalla.
    useEffect(function () {
      const onKey = function (e) {
        if (e.key === "Escape" && !modalAbierto) onCerrar && onCerrar();
      };
      document.addEventListener("keydown", onKey);
      return function () { document.removeEventListener("keydown", onKey); };
    }, [modalAbierto, onCerrar]);

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

    // Lista de asistentes inline (reemplaza el cuerpo del panel).
    // Misma técnica que MisIglesias → GestionarIglesia: early-return.
    if (viendoAsistentesDe && window.ListaAsistentes) {
      return React.createElement(window.ListaAsistentes, {
        iglesia: iglesia,
        actividad: viendoAsistentesDe,
        onCerrar: function () { setViendoAsistentesDe(null); },
      });
    }

    // Sin permisos → pantalla explicativa con volver.
    if (!puedeGestionar) {
      return (
        <div className="fade-in" style={{ paddingBottom: 96 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 6, padding: "16px 16px 8px" }}>
            <button
              type="button"
              onClick={onCerrar}
              aria-label="Atrás"
              style={{
                width: 32, height: 32, borderRadius: 999,
                border: "none", background: "transparent",
                color: colorTexto, cursor: "pointer",
                display: "flex", alignItems: "center", justifyContent: "center",
                marginLeft: -6,
              }}
            >
              {BackIcon ? <BackIcon /> : <span style={{ fontSize: 20 }}>←</span>}
            </button>
            <h2 style={{ margin: 0, fontSize: 18, fontWeight: 900, color: colorTexto }}>
              Sin permisos
            </h2>
          </div>
          <div style={{ padding: "20px 16px", textAlign: "center" }}>
            <div style={{ fontSize: 44, lineHeight: 1, marginBottom: 10 }} aria-hidden>🔒</div>
            <div style={{ fontSize: 14, fontWeight: 700, color: colorTexto, marginBottom: 4 }}>
              No puede gestionar actividades de esta iglesia.
            </div>
            <div style={{ fontSize: 12, fontWeight: 600, color: colorSecundario, lineHeight: 1.5 }}>
              Pida al pastor que le asigne el rol "Actividades Espirituales".
            </div>
          </div>
        </div>
      );
    }

    return (
      <div className="fade-in" style={{ paddingBottom: 96 }}>
        {/* Encabezado inline */}
        <div style={{ display: "flex", alignItems: "flex-start", gap: 6, padding: "16px 16px 10px" }}>
          <button
            type="button"
            onClick={onCerrar}
            aria-label="Atrás"
            style={{
              width: 32, height: 32, borderRadius: 999,
              border: "none", background: "transparent",
              color: colorTexto, cursor: "pointer",
              display: "flex", alignItems: "center", justifyContent: "center",
              flexShrink: 0, marginLeft: -6,
            }}
          >
            {BackIcon ? <BackIcon /> : <span style={{ fontSize: 20 }}>←</span>}
          </button>
          <div style={{ flex: 1, minWidth: 0, paddingTop: 2 }}>
            <div style={{ fontSize: 18, fontWeight: 900, color: colorTexto, lineHeight: 1.15 }}>
              Actividades
            </div>
            <div
              style={{
                fontSize: 12, fontWeight: 700, color: colorSecundario,
                marginTop: 2, overflow: "hidden",
                textOverflow: "ellipsis", whiteSpace: "nowrap",
              }}
            >
              {(iglesia && iglesia.nombre) || ""}
            </div>
          </div>
        </div>

        {/* Banner rol (si aplica) */}
        {!esPastorOwner && !esSuper && tieneRolActividades && (
          <div
            style={{
              margin: "0 16px 10px",
              padding: "10px 12px",
              borderRadius: 12,
              border: "1px solid " + (dark ? "#1E3A8A" : "#BFDBFE"),
              background: bgBanner,
              display: "flex", alignItems: "flex-start", gap: 10,
            }}
          >
            <div style={{ fontSize: 18, lineHeight: 1 }} aria-hidden>✨</div>
            <div style={{ fontSize: 12, fontWeight: 700, color: colorBanner, lineHeight: 1.4 }}>
              Está gestionando actividades como <strong>Actividades Espirituales</strong>.
              Puede publicar y editar los eventos puntuales de esta iglesia.
            </div>
          </div>
        )}

        <div style={{ padding: "0 16px" }}>
          {cargando && (
            <div
              style={{
                display: "flex", flexDirection: "column",
                alignItems: "center", padding: "36px 16px", gap: 10,
              }}
            >
              <div
                style={{
                  width: 26, height: 26,
                  border: "3px solid " + colorBorde,
                  borderTopColor: BRAND,
                  borderRadius: "50%",
                  animation: "gactSpin 0.9s linear infinite",
                }}
              />
              <div style={{ fontSize: 12, fontWeight: 700, color: colorSecundario }}>
                Cargando actividades…
              </div>
            </div>
          )}

          {!cargando && actividades.length === 0 && (
            <div
              style={{
                display: "flex", flexDirection: "column",
                alignItems: "center", textAlign: "center",
                padding: "36px 20px", gap: 10,
              }}
            >
              <div style={{ fontSize: 48, lineHeight: 1 }} aria-hidden>✨</div>
              <div style={{ fontSize: 15, fontWeight: 900, color: colorTexto }}>
                Aún no hay actividades publicadas
              </div>
              <div
                style={{
                  fontSize: 13, fontWeight: 600, color: colorSecundario,
                  maxWidth: 320, lineHeight: 1.5,
                }}
              >
                Publique retiros, vigilias, campañas y otros eventos puntuales
                para que los miembros y amigos de la iglesia los vean.
              </div>
              <button
                type="button"
                onClick={abrirPublicar}
                style={{
                  marginTop: 6,
                  padding: "12px 18px",
                  borderRadius: 14,
                  border: "none",
                  background: GREEN,
                  color: "#FFFFFF",
                  fontSize: 14, fontWeight: 900,
                  cursor: "pointer",
                  boxShadow: "0 4px 0 " + GREEN_SHADOW,
                  letterSpacing: 0.2,
                }}
              >
                + Publicar actividad
              </button>
            </div>
          )}

          {!cargando && actividades.length > 0 && (
            <React.Fragment>
              <div style={{ display: "flex", justifyContent: "flex-end", marginBottom: 10 }}>
                <button
                  type="button"
                  onClick={abrirPublicar}
                  style={{
                    padding: "10px 14px",
                    borderRadius: 14,
                    border: "none",
                    background: GREEN,
                    color: "#FFFFFF",
                    fontSize: 13, fontWeight: 900,
                    cursor: "pointer",
                    boxShadow: "0 4px 0 " + GREEN_SHADOW,
                  }}
                >
                  + Publicar actividad
                </button>
              </div>

              <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
                {actividades.map(function (act) {
                  const t = TIPOS_ACTIVIDAD[act.tipo] || TIPOS_ACTIVIDAD.otro;
                  const tipoLabel = act.tipo === "otro" && act.tipo_otro
                    ? act.tipo_otro
                    : t.label;
                  return (
                    <div
                      key={act.id}
                      style={{
                        display: "flex",
                        gap: 12,
                        padding: 12,
                        borderRadius: 14,
                        border: "1px solid " + colorBorde,
                        background: bgCard,
                        boxShadow: shadowCard,
                      }}
                    >
                      {/* Miniatura flyer vertical 3:4 */}
                      <div
                        style={{
                          width: 70, height: 93,
                          borderRadius: 10,
                          overflow: "hidden",
                          flexShrink: 0,
                          background: bgPlaceholder,
                          display: "flex",
                          alignItems: "center",
                          justifyContent: "center",
                        }}
                      >
                        {act.imagen_url ? (
                          <img
                            src={act.imagen_url}
                            alt=""
                            referrerPolicy="no-referrer"
                            style={{ width: "100%", height: "100%", objectFit: "cover" }}
                          />
                        ) : (
                          <div style={{ fontSize: 32, lineHeight: 1 }} aria-hidden>
                            {t.emoji}
                          </div>
                        )}
                      </div>

                      <div style={{ flex: 1, minWidth: 0 }}>
                        <div
                          style={{
                            fontSize: 14, fontWeight: 900, color: colorTexto,
                            lineHeight: 1.2,
                            overflow: "hidden",
                            display: "-webkit-box",
                            WebkitLineClamp: 2,
                            WebkitBoxOrient: "vertical",
                          }}
                        >
                          {act.titulo || "Sin título"}
                        </div>

                        <div
                          style={{
                            display: "inline-flex", alignItems: "center", gap: 4,
                            background: bgBadgeTipo, color: colorBadgeTipo,
                            padding: "2px 8px", borderRadius: 999,
                            fontSize: 10, fontWeight: 800, letterSpacing: 0.3,
                            marginTop: 6,
                          }}
                        >
                          <span aria-hidden>{t.emoji}</span>
                          <span>{tipoLabel}</span>
                        </div>

                        <div style={{ fontSize: 11, fontWeight: 700, color: colorSecundario, marginTop: 4 }}>
                          📅 {fmtRangoFechas(act.fecha_inicio, act.fecha_fin)}
                          {act.hora ? "  ·  🕒 " + fmtHora12(act.hora) : ""}
                        </div>
                        {act.ubicacion && (
                          <div
                            style={{
                              fontSize: 11, fontWeight: 600, color: colorSecundario, marginTop: 2,
                              overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap",
                            }}
                          >
                            📍 {act.ubicacion}
                          </div>
                        )}

                        {/* Fila tappable de asistencias. Abre ListaAsistentes. */}
                        {(function () {
                          const total = contadores[act.id] || 0;
                          const texto = total === 0
                            ? "Aún nadie ha marcado · Ver lista"
                            : "✋ " + total + (total === 1 ? " persona asistirá" : " personas asistirán");
                          return (
                            <button
                              type="button"
                              onClick={function () { setViendoAsistentesDe(act); }}
                              style={{
                                marginTop: 6,
                                padding: "4px 0 0",
                                border: "none",
                                background: "transparent",
                                color: total > 0 ? BRAND : colorSecundario,
                                fontSize: 11,
                                fontWeight: 800,
                                letterSpacing: 0.2,
                                cursor: "pointer",
                                textAlign: "left",
                                fontFamily: "inherit",
                                textDecoration: "none",
                              }}
                              aria-label="Ver lista de asistentes"
                            >
                              {texto}
                            </button>
                          );
                        })()}

                        <div style={{ display: "flex", gap: 6, marginTop: 8 }}>
                          <button
                            type="button"
                            onClick={function () { abrirEditar(act); }}
                            style={{
                              padding: "6px 10px",
                              borderRadius: 999,
                              border: "1px solid " + colorBorde,
                              background: "transparent",
                              color: BRAND,
                              fontSize: 11, fontWeight: 900, letterSpacing: 0.3,
                              cursor: "pointer",
                            }}
                          >
                            Editar
                          </button>
                          <button
                            type="button"
                            onClick={function () { setRevocarActividad(act); }}
                            style={{
                              padding: "6px 10px",
                              borderRadius: 999,
                              border: "1px solid " + colorBorde,
                              background: "transparent",
                              color: DANGER,
                              fontSize: 11, fontWeight: 900, letterSpacing: 0.3,
                              cursor: "pointer",
                            }}
                          >
                            Eliminar
                          </button>
                        </div>
                      </div>
                    </div>
                  );
                })}
              </div>
            </React.Fragment>
          )}
        </div>

        {modalAbierto && iglesia && (
          <PublicarActividadModal
            iglesia={iglesia}
            actividadEditando={actividadEditando}
            onCerrar={function () { setModalAbierto(false); setActividadEditando(null); }}
            onGuardado={function () { mostrarToast(actividadEditando ? "Actividad actualizada ✓" : "Actividad publicada ✓"); }}
          />
        )}

        {revocarActividad && window.ConfirmModal && React.createElement(window.ConfirmModal, {
          abierto: !!revocarActividad,
          titulo: "Eliminar actividad",
          mensaje: revocarActividad
            ? "¿Eliminar \"" + (revocarActividad.titulo || "esta actividad") + "\"? Esta acción no se puede deshacer."
            : "",
          textoConfirmar: "Eliminar",
          textoCancelar: "Cancelar",
          tono: "peligro",
          cargando: eliminandoEnCurso,
          onConfirmar: ejecutarEliminar,
          onCancelar: function () { if (!eliminandoEnCurso) setRevocarActividad(null); },
        })}

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

        <style>{`
          @keyframes gactSpin { to { transform: rotate(360deg); } }
        `}</style>
      </div>
    );
  }

  window.GestionarActividades = GestionarActividades;
})();
