/* Home → window. Dashboard de iglesias cercanas.
   RecordRow y EmptyState se mantienen expuestos porque Historial los usa. */
(function () {
  const { useMemo, useState, useEffect } = React;
  const {
    useData, fmt, fmtDiaCorto, MESES,
    netoOf, sumRecords, recordsOfMonth, recordsOfCurrentWeek,
    IglesiaCard, ActividadCard, enriquecerIglesias,
  } = window;

  function RecordRow({ item, onEdit }) {
    const neto = netoOf(item);
    const hasNota = !!(item.nota && item.nota.length);
    return (
      <button onClick={() => onEdit && onEdit(item)} className="card-soft px-4 py-3 w-full text-left active:scale-[0.98] transition">
        <div className="flex items-center justify-between mb-2">
          <div className="font-black text-[#3C3C3C] text-base">{fmtDiaCorto(item.fecha)}</div>
          <div className="flex items-baseline gap-1">
            <span className="text-[10px] font-black uppercase text-[#777] tracking-wide">Neto</span>
            <span className={"text-base font-black whitespace-nowrap " + (neto >= 0 ? "text-[#3C3C3C]" : "text-[#FF4B4B]")}>{fmt(neto)}</span>
          </div>
        </div>

        <div className="grid grid-cols-3 gap-1 text-center bg-[#F9F9F9] rounded-xl py-2 px-1">
          <div>
            <div className="text-[9px] font-black uppercase text-[#777] tracking-wide">Ingreso</div>
            <div className="text-xs font-black text-[#58CC02] whitespace-nowrap">+{fmt(item.ingreso)}</div>
          </div>
          <div className="border-x border-[#EEE]">
            <div className="text-[9px] font-black uppercase text-[#777] tracking-wide">Gasolina</div>
            <div className="text-xs font-black text-[#FF4B4B] whitespace-nowrap">-{fmt(item.gasolina)}</div>
          </div>
          <div>
            <div className="text-[9px] font-black uppercase text-[#777] tracking-wide">Mantenim.</div>
            <div className="text-xs font-black text-[#D4A200] whitespace-nowrap">-{fmt(item.mantenimiento || 0)}</div>
          </div>
        </div>

        {hasNota && (
          <div className="mt-2 text-xs text-[#777] font-semibold italic flex items-start gap-1">
            <span>📝</span><span className="flex-1 truncate">{item.nota}</span>
          </div>
        )}
      </button>
    );
  }

  function EmptyState({ title, subtitle }) {
    return (
      <div className="card-soft p-6 text-center">
        <div className="text-5xl mb-2">📋</div>
        <div className="font-black text-[#3C3C3C]">{title}</div>
        <div className="text-sm font-semibold text-[#777] mt-1">{subtitle}</div>
      </div>
    );
  }

  const PAGE_SIZE = 7; // Instagram/FB style: batches of 7.
  const { useRef } = React;

  function Home({ onSelect, onShowMap, iglesias, iglesiasEnRango, banner, ubicacionEfectiva, alcanceKm, onConfigurarUbicacion }) {
    const lista = Array.isArray(iglesias) ? iglesias : [];
    const enRango = Array.isArray(iglesiasEnRango) ? iglesiasEnRango : [];
    const [ahora, setAhora] = useState(() => new Date());
    const [actividades, setActividades] = useState([]);
    const [visibles, setVisibles] = useState(PAGE_SIZE);
    // Bottom sheet con el horario semanal de una iglesia. Se abre al
    // tocar el bloque de próximo culto o el chip "Horario" en la
    // IglesiaCard. El tap en la card completa sigue abriendo DetalleIglesia.
    const [horarioDe, setHorarioDe] = useState(null);

    // Set de ids en rango para filtrar actividades de manera O(1).
    const idsEnRango = useMemo(function () {
      var s = {};
      enRango.forEach(function (ig) { if (ig && ig.id) s[ig.id] = true; });
      return s;
    }, [enRango]);

    // Estados de la ubicación efectiva para orquestar la UI.
    const estadoUbic = (ubicacionEfectiva && ubicacionEfectiva.estado) || "sin_config";
    const ubicacionResuelta = (estadoUbic === "gps_activo" || estadoUbic === "manual_activo");
    const ubicacionDetectando = (estadoUbic === "detectando");
    const ubicacionNecesitaAccion = !ubicacionResuelta && !ubicacionDetectando;

    // Refresh de `ahora` cada 60s → recalcula scores, badges y el
    // "hace X tiempo" de las publicaciones sin re-fetch.
    useEffect(() => {
      const id = setInterval(() => setAhora(new Date()), 60000);
      return () => clearInterval(id);
    }, []);

    // Feed de actividades: suscribimos SOLO las iglesias que están en
    // rango. Así el backend no nos trae actividades de iglesias fuera
    // del alcance — sería costoso y el usuario no las vería igual.
    const rangoKey = enRango.map(function (x) { return x && x.id; }).sort().join(",");
    useEffect(() => {
      if (typeof window.suscribirActividadesDeIglesias !== "function" || enRango.length === 0) {
        setActividades([]);
        return;
      }
      const unsub = window.suscribirActividadesDeIglesias(enRango, function (arr) {
        setActividades(Array.isArray(arr) ? arr : []);
      });
      return function () { if (typeof unsub === "function") unsub(); };
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [rangoKey]);

    // Enriquecemos las iglesias en rango (ya tienen distancia_km del
    // filtro). La llamada a enriquecerIglesias reusa el cálculo de
    // proximo_culto/score; el sort final vuelve a ordenarse por score.
    const iglesiasEnriquecidas = useMemo(() => {
      if (typeof enriquecerIglesias !== "function") return enRango;
      return enriquecerIglesias(enRango, ubicacionEfectiva, ahora);
    }, [enRango, ubicacionEfectiva, ahora]);

    // Feed unificado: mezclamos iglesias en rango + actividades en rango.
    // Las actividades se cruzan contra idsEnRango por si el listener
    // aún no refrescó tras un cambio de alcance.
    const publicaciones = useMemo(function () {
      var items = [];
      actividades.forEach(function (act) {
        var igId = act && act.iglesia && act.iglesia.id;
        if (!igId || !idsEnRango[igId]) return;
        items.push({
          kind: "actividad",
          key: "act_" + igId + "_" + act.id,
          ts: typeof act.publicado_en === "number" ? act.publicado_en : 0,
          data: act,
        });
      });
      iglesiasEnriquecidas.forEach(function (ig) {
        // Las iglesias no reclamadas NO aparecen en el feed (regla de
        // producto: aparecen en Buscador y Radar con badge, pero no
        // saturan el scroll). Siguen existiendo; el pastor que las
        // encuentra las reclama desde DetalleIglesia.
        if (ig && ig.reclamada === false) return;
        items.push({
          kind: "iglesia",
          key: "ig_" + ig.id,
          ts: typeof ig.createdAt === "number"
            ? ig.createdAt
            : (typeof ig.updatedAt === "number" ? ig.updatedAt : 0),
          data: ig,
        });
      });
      items.sort(function (a, b) { return b.ts - a.ts; });
      return items;
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [actividades, iglesiasEnriquecidas, idsEnRango]);

    // Si cambia el tamaño del feed (ej. nueva actividad publicada),
    // aseguramos que el usuario siga viendo al menos PAGE_SIZE nuevos.
    useEffect(function () {
      setVisibles(function (prev) {
        if (publicaciones.length === 0) return PAGE_SIZE;
        return Math.min(Math.max(prev, PAGE_SIZE), publicaciones.length);
      });
    }, [publicaciones.length]);

    const hayMas = visibles < publicaciones.length;

    // IntersectionObserver sobre un "sentinel" al final: cuando se
    // acerca al viewport, cargamos el siguiente lote.
    const sentinelRef = useRef(null);
    useEffect(function () {
      if (!hayMas || !sentinelRef.current) return;
      const el = sentinelRef.current;
      const obs = new IntersectionObserver(function (entries) {
        entries.forEach(function (entry) {
          if (entry.isIntersecting) {
            setVisibles(function (v) {
              return Math.min(v + PAGE_SIZE, publicaciones.length);
            });
          }
        });
      }, { rootMargin: "240px" });
      obs.observe(el);
      return function () { obs.disconnect(); };
    }, [hayMas, publicaciones.length]);

    const visiblesArr = publicaciones.slice(0, visibles);

    return (
      <div className="fade-in pb-40">
        {banner}

        {/* Ubicación sin resolver (denegada / no disponible / sin config):
            empty-state con CTA. Antes vivía en una banda superior
            (UbicacionIndicador) pero se consolidó aquí para no
            duplicar avisos. */}
        {ubicacionNecesitaAccion && (
          <div className="px-5 mt-8">
            <div className="card-soft p-6 text-center">
              <div className="text-5xl mb-2">📍</div>
              <div className="font-black text-[#3C3C3C] dark:text-gray-100">
                {estadoUbic === "gps_denegado"
                  ? "Permiso de ubicación denegado"
                  : estadoUbic === "gps_no_disponible"
                    ? "No pudimos obtener tu ubicación"
                    : "Necesitamos tu ubicación"}
              </div>
              <div className="text-sm font-semibold text-[#777] dark:text-gray-400 mt-1">
                {estadoUbic === "gps_denegado"
                  ? "Actívala en tu navegador o elige una provincia para descubrir iglesias cerca de ti."
                  : "Activa tu ubicación o elige una provincia para descubrir iglesias cerca de ti."}
              </div>
              <button
                type="button"
                onClick={onConfigurarUbicacion}
                className="mt-4 inline-flex items-center gap-2 px-4 py-2 rounded-full bg-[#2563EB] text-white text-sm font-black active:opacity-80 transition"
              >
                <span aria-hidden>⚙️</span>
                <span>Configurar ubicación</span>
              </button>
            </div>
          </div>
        )}

        {/* Ubicación detectando y aún no emitió lat/lng — sutil. */}
        {ubicacionDetectando && publicaciones.length === 0 && (
          <div className="px-5 mt-8 text-center">
            <div className="text-sm font-semibold text-[#9AA0A6] dark:text-gray-500">
              Buscando iglesias cerca de ti…
            </div>
          </div>
        )}

        {/* Ubicación resuelta pero nada en rango — empty state con CTA. */}
        {ubicacionResuelta && publicaciones.length === 0 && (
          <div className="px-5 mt-8">
            <div className="card-soft p-6 text-center">
              <div className="text-5xl mb-2">🔎</div>
              <div className="font-black text-[#3C3C3C] dark:text-gray-100">
                Nada para mostrar en el feed
              </div>
              <div className="text-sm font-semibold text-[#777] dark:text-gray-400 mt-1">
                {ubicacionEfectiva.estado === "manual_activo"
                  ? "No hay iglesias a " + alcanceKm + " km de " + (ubicacionEfectiva.provincia || "esta provincia") + ". Amplía el rango para ver más."
                  : "No hay iglesias a " + alcanceKm + " km de ti. Amplía el rango para ver más."}
              </div>
              <button
                type="button"
                onClick={onConfigurarUbicacion}
                className="mt-4 inline-flex items-center gap-2 px-4 py-2 rounded-full bg-[#2563EB] text-white text-sm font-black active:opacity-80 transition"
              >
                <span aria-hidden>📏</span>
                <span>Ampliar rango</span>
              </button>
            </div>
          </div>
        )}

        {publicaciones.length > 0 && (
          <div className="mt-3">
            {visiblesArr.map(function (item) {
              if (item.kind === "actividad" && ActividadCard) {
                return (
                  <ActividadCard
                    key={item.key}
                    actividad={item.data}
                    ahoraTick={ahora.getTime()}
                    onTapIglesia={function (iglesiaLite) {
                      const full = lista.find(function (x) { return x && x.id === iglesiaLite.id; });
                      if (typeof onSelect === "function") onSelect(full || iglesiaLite);
                    }}
                  />
                );
              }
              if (item.kind === "iglesia") {
                return (
                  <IglesiaCard
                    key={item.key}
                    iglesia={item.data}
                    onTap={onSelect}
                    onShowMap={onShowMap}
                    onShowHorario={setHorarioDe}
                  />
                );
              }
              return null;
            })}

            {/* Sentinel + loader: cuando entra al viewport, carga +7. */}
            {hayMas && (
              <div
                ref={sentinelRef}
                style={{
                  display: "flex",
                  alignItems: "center",
                  justifyContent: "center",
                  padding: "20px 12px",
                  gap: 10,
                }}
              >
                <div
                  style={{
                    width: 22, height: 22,
                    border: "3px solid #E5E7EB",
                    borderTopColor: "#2563EB",
                    borderRadius: "50%",
                    animation: "homeFeedSpin 0.9s linear infinite",
                  }}
                />
                <div className="text-xs font-bold text-[#777] dark:text-gray-400">
                  Cargando más…
                </div>
                <style>{`@keyframes homeFeedSpin { to { transform: rotate(360deg); } }`}</style>
              </div>
            )}
            {!hayMas && publicaciones.length > PAGE_SIZE && (
              <div className="text-center text-xs font-bold text-[#9AA0A6] dark:text-gray-500 py-6">
                Llegaste al final · {publicaciones.length} publicaciones
              </div>
            )}
          </div>
        )}

        {window.HorarioSheet && (
          <window.HorarioSheet
            abierto={!!horarioDe}
            iglesia={horarioDe || {}}
            onClose={() => setHorarioDe(null)}
            onVerIglesia={horarioDe ? () => {
              const ig = horarioDe;
              setHorarioDe(null);
              if (typeof onSelect === "function") onSelect(ig);
            } : null}
          />
        )}
      </div>
    );
  }

  Object.assign(window, { Home, RecordRow, EmptyState });

  // LEGACY: dashboard motoristas, se reactivará si es necesario.
  // Se mantiene aquí como referencia histórica. MonthCard dependía de
  // useData/sumRecords/recordsOfMonth/MESES; Home anterior dependía de
  // recordsOfCurrentWeek y mostraba MonthCard + lista semanal.
  //
  // function MonthCard() {
  //   const { records } = useData();
  //   const d = new Date();
  //   const totals = useMemo(
  //     () => sumRecords(recordsOfMonth(records, d.getFullYear(), d.getMonth())),
  //     [records]
  //   );
  //   return (
  //     <div className="mx-5 rounded-3xl p-6 text-white relative overflow-hidden"
  //          style={{ background: "linear-gradient(160deg,#58CC02 0%,#2A5E00 100%)", boxShadow: "0 6px 18px rgba(42,94,0,0.2)" }}>
  //       <div className="text-center font-bold uppercase tracking-widest text-xs opacity-80">
  //         {MESES[d.getMonth()]} {d.getFullYear()}
  //       </div>
  //       <div className="mt-5 grid grid-cols-3 gap-2">
  //         <div>
  //           <div className="text-[10px] font-bold uppercase opacity-80">Ganado</div>
  //           <div className="text-sm font-black text-[#DFFBC2]">{fmt(totals.ingreso)}</div>
  //         </div>
  //         <div className="text-center">
  //           <div className="text-[10px] font-bold uppercase opacity-80">Gasolina</div>
  //           <div className="text-sm font-black text-[#FFB4B4]">{fmt(totals.gasolina)}</div>
  //         </div>
  //         <div className="text-right">
  //           <div className="text-[10px] font-bold uppercase opacity-80">Mantenim.</div>
  //           <div className="text-sm font-black text-[#FFE08A]">{fmt(totals.mantenimiento)}</div>
  //         </div>
  //       </div>
  //       <div className="mt-5 text-center">
  //         <div className="text-xs font-bold uppercase opacity-80">Neto del mes</div>
  //         <div className="text-4xl font-black mt-1">{fmt(totals.neto)}</div>
  //       </div>
  //     </div>
  //   );
  // }
  //
  // function HomeMotoristas({ onEditRecord }) {
  //   const { records } = useData();
  //   const week = useMemo(() => recordsOfCurrentWeek(records), [records]);
  //   const weekTotals = useMemo(() => sumRecords(week), [week]);
  //   return (
  //     <div className="fade-in pb-40">
  //       <MonthCard />
  //       <div className="px-5 mt-6">
  //         <div className="flex justify-between items-end mb-3">
  //           <h2 className="font-black text-[#3C3C3C] text-lg">Esta semana</h2>
  //           {week.length > 0 && (
  //             <span className="text-sm font-black text-[#58CC02]">{fmt(weekTotals.neto)}</span>
  //           )}
  //         </div>
  //         {week.length === 0 ? (
  //           <EmptyState title="Sin registros esta semana" subtitle="Toca el botón + para agregar tu primer día" />
  //         ) : (
  //           <div className="space-y-3">
  //             {week.map(it => <RecordRow key={it.fecha} item={it} onEdit={onEditRecord} />)}
  //           </div>
  //         )}
  //       </div>
  //     </div>
  //   );
  // }
})();
