// TikTok-style vertical video feed. Full-bleed, swipe/scroll/keys.
// Mounted at #feed (mobile + desktop) and reachable from a floating
// button on the home / shadow pages and a nav-drawer entry.
// Uses IntersectionObserver to autoplay only the visible video.

function VideoFeedPage({ nav, params }) {
  const cat = useVideoCatalog();
  const familyStories = useFamilyStories();
  const kind = params?.kind || "all";
  // Build the three source lists.
  const lists = useMemo(() => {
    const music = (cat.videos || []).map(v => ({
      id: v.id, shorts: v.shorts, full: v.full, title: v.title,
      scripture: v.scripture, psalm: v.psalm, collectionTitle: v.collectionTitle,
    }));
    const stories = [];
    const storyList = [{ id: "jacob", name: "Jacob — Israel" }, ...TRIBES.map(t => ({ id: t.id, name: t.name }))];
    storyList.forEach(s => {
      const sv = (typeof storyVideo === "function") ? storyVideo(s.id) : null;
      if (sv) stories.push({ id: "story-" + s.id, shorts: sv.preview, full: sv.full, title: s.name, scripture: null, collectionTitle: "Biblical Stories" });
    });
    const insp = [];
    if (window.TRIBE_INSPIRATIONS) {
      Object.entries(window.TRIBE_INSPIRATIONS).forEach(([tribeN, items]) => {
        (items || []).forEach(item => insp.push({ id: "insp-" + tribeN + "-" + item.id, shorts: item.videoUrl, full: item.videoUrl, title: "Reflection " + item.id, scripture: null, collectionTitle: "Inspirations" }));
      });
    }
    const family = (familyStories || []).map(f => ({
      id: f.id, shorts: f.shorts, full: f.full, title: f.title,
      scripture: null, collectionTitle: f.collectionTitle,
    }));
    return { music, stories, insp, family };
  }, [cat.videos, familyStories]);

  const list = useMemo(() => {
    if (kind === "music") return lists.music;
    if (kind === "stories") return lists.stories;
    if (kind === "inspirations") return lists.insp;
    if (kind === "family") return lists.family;
    // "all" — mix every series and shuffle randomly.
    const merged = [...lists.music, ...lists.stories, ...lists.insp, ...lists.family];
    for (let i = merged.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [merged[i], merged[j]] = [merged[j], merged[i]];
    }
    return merged;
  }, [lists, kind]);

  const startId = params?.id;
  const containerRef = useRef(null);
  const [activeIdx, setActiveIdx] = useState(0);
  const [muted, setMuted] = useState(true);
  const [autoplay, setAutoplay] = useState(() => {
    try { return localStorage.getItem("feedAutoplay") !== "off"; } catch { return true; }
  });
  useEffect(() => { try { localStorage.setItem("feedAutoplay", autoplay ? "on" : "off"); } catch {} }, [autoplay]);
  const p = usePlayer();

  // Pause any sticky audio while the feed is active — only one media at a time.
  useEffect(() => {
    if (p.playing) p.toggle();
    return () => {};
  }, []);

  // Scroll to the starting video on mount
  useEffect(() => {
    if (!containerRef.current) return;
    if (!list.length) return;
    const idx = startId ? Math.max(0, list.findIndex(v => v.id === startId)) : 0;
    const el = containerRef.current.children[idx];
    if (el) el.scrollIntoView({ behavior: "instant", block: "start" });
    setActiveIdx(idx);
  }, [list.length]);

  // Detect which slide is in view
  useEffect(() => {
    const c = containerRef.current;
    if (!c) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting && entry.intersectionRatio > 0.6) {
          const idx = Number(entry.target.dataset.idx);
          setActiveIdx(idx);
        }
      });
    }, { root: c, threshold: [0.6] });
    Array.from(c.children).forEach((child) => io.observe(child));
    return () => io.disconnect();
  }, [list.length]);

  // Keyboard nav
  useEffect(() => {
    const onKey = (e) => {
      if (e.key === "ArrowDown" || e.key === "j") {
        e.preventDefault();
        scrollBy(1);
      } else if (e.key === "ArrowUp" || e.key === "k") {
        e.preventDefault();
        scrollBy(-1);
      } else if (e.key === "m") {
        setMuted(m => !m);
      } else if (e.key === "Escape") {
        window.history.back();
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [activeIdx, list.length]);

  function scrollBy(delta) {
    const c = containerRef.current;
    if (!c) return;
    const nextIdx = Math.max(0, Math.min(list.length - 1, activeIdx + delta));
    const el = c.children[nextIdx];
    if (el) el.scrollIntoView({ behavior: "smooth", block: "start" });
  }

  // Autoplay advance — wraps to the first clip after the last for a continuous cycle.
  function advanceAuto() {
    const c = containerRef.current;
    if (!c) return;
    const ni = activeIdx + 1 >= list.length ? 0 : activeIdx + 1;
    const el = c.children[ni];
    if (el) el.scrollIntoView({ behavior: "smooth", block: "start" });
  }

  if (!list.length) {
    return (
      <div style={{ minHeight: "100vh", background: "#000", color: T.paper, display: "flex", alignItems: "center", justifyContent: "center", padding: 24 }}>
        <div style={{ textAlign: "center" }}>
          <SmallCaps color={T.gold} size={11}>Loading the feed…</SmallCaps>
        </div>
      </div>
    );
  }

  return (
    <div style={{ position: "fixed", inset: 0, zIndex: 100, background: "#000", overflow: "hidden" }}>
      {/* Scroll container */}
      <div
        ref={containerRef}
        style={{
          height: "100dvh",
          overflowY: "scroll",
          scrollSnapType: "y mandatory",
          WebkitOverflowScrolling: "touch",
          scrollbarWidth: "none",
        }}
      >
        {list.map((v, i) => (
          <FeedSlide
            key={v.id}
            video={v}
            idx={i}
            active={i === activeIdx}
            near={Math.abs(i - activeIdx) <= 1}
            muted={muted}
            autoplay={autoplay}
            onAdvance={advanceAuto}
            nav={nav}
          />
        ))}
      </div>

      {/* Top bar */}
      <div style={{
        position: "absolute", top: 0, left: 0, right: 0, zIndex: 5,
        padding: "calc(14px + env(safe-area-inset-top)) 14px 14px",
        display: "flex", justifyContent: "space-between", alignItems: "center",
        background: "linear-gradient(180deg, rgba(0,0,0,0.55), transparent)",
        pointerEvents: "none",
      }}>
        <button onClick={() => window.history.back()} aria-label="Close" style={{
          width: 40, height: 40, background: "rgba(0,0,0,0.4)",
          border: `1px solid ${T.gold}44`, color: T.paper, cursor: "pointer",
          backdropFilter: "blur(8px)", pointerEvents: "auto",
          display: "flex", alignItems: "center", justifyContent: "center",
        }}>
          <svg width="14" height="14" viewBox="0 0 14 14" stroke="currentColor" strokeWidth="2" fill="none">
            <line x1="3" y1="3" x2="11" y2="11" /><line x1="11" y1="3" x2="3" y2="11" />
          </svg>
        </button>
        <div style={{ pointerEvents: "auto" }}>
          <SmallCaps color={T.gold} letterSpacing="0.4em" size={10}>The Feed</SmallCaps>
        </div>
        <div style={{ display: "flex", gap: 8, alignItems: "center", pointerEvents: "auto" }}>
          {/* Autoplay toggle — gold when on, default on, persisted */}
          <button onClick={() => setAutoplay(a => !a)} aria-label="Autoplay" title="Autoplay next" style={{
            display: "flex", alignItems: "center", gap: 5, padding: "0 12px", height: 40,
            background: autoplay ? T.gold : "rgba(0,0,0,0.4)", color: autoplay ? T.ink : T.gold,
            border: `1px solid ${T.gold}${autoplay ? "" : "44"}`, cursor: "pointer", backdropFilter: "blur(8px)",
            fontFamily: "'Cinzel', serif", fontSize: 10, letterSpacing: "0.16em", fontWeight: autoplay ? 700 : 500,
          }}>
            <svg width="11" height="11" viewBox="0 0 16 16" fill="currentColor"><path d="M3 2l11 6-11 6V2z" /></svg>AUTO
          </button>
          {/* Mute/Unmute toggle — gold text + icon */}
          <button onClick={() => setMuted(m => !m)} aria-label={muted ? "Unmute" : "Mute"} style={{
            display: "flex", alignItems: "center", gap: 6, padding: "0 12px", height: 40,
            background: "rgba(0,0,0,0.4)", border: `1px solid ${T.gold}44`, color: T.gold, cursor: "pointer",
            backdropFilter: "blur(8px)", fontFamily: "'Cinzel', serif", fontSize: 10, letterSpacing: "0.16em", fontWeight: 600,
          }}>
            {muted ? (
              <svg width="15" height="15" viewBox="0 0 16 16" fill="currentColor"><path d="M3 6h2l3-3v10l-3-3H3V6z" /><path d="M11 6l3 3M14 6l-3 3" stroke="currentColor" strokeWidth="1.4" fill="none" /></svg>
            ) : (
              <svg width="15" height="15" viewBox="0 0 16 16" fill="currentColor"><path d="M3 6h2l3-3v10l-3-3H3V6z" /><path d="M11 5a3 3 0 010 6" stroke="currentColor" strokeWidth="1.4" fill="none" /></svg>
            )}
            {muted ? "UNMUTE" : "MUTE"}
          </button>
        </div>
      </div>

      {/* Bottom hint — flip for more */}
      <div style={{
        position: "absolute", bottom: "calc(14px + env(safe-area-inset-bottom))", left: 0, right: 0,
        textAlign: "center", pointerEvents: "none", zIndex: 5,
      }}>
        <SmallCaps color={T.gold} letterSpacing="0.3em" size={10} style={{ background: "rgba(0,0,0,0.5)", padding: "6px 14px", display: "inline-flex", alignItems: "center", gap: 8 }}>
          Flip for more
          <svg width="11" height="11" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2" style={{ animation: "feedFlipBob 1.6s ease-in-out infinite" }}><path d="M8 2v11M3 8l5 5 5-5" /></svg>
        </SmallCaps>
      </div>

      <style>{`
        .feed-scroll::-webkit-scrollbar { display: none; }
        @keyframes feedFlipBob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(3px); } }
      `}</style>
    </div>
  );
}

// Single full-bleed slide
function FeedSlide({ video, idx, active, near, muted, autoplay, onAdvance, nav }) {
  const videoRef = useRef(null);

  useEffect(() => {
    const v = videoRef.current;
    if (!v) return;
    v.muted = muted;
    if (active) {
      v.currentTime = 0;
      v.play().catch(() => {});
    } else {
      v.pause();
    }
  }, [active, muted, near]);

  const onTap = () => {
    const v = videoRef.current;
    if (!v) return;
    if (v.paused) v.play().catch(() => {});
    else v.pause();
  };

  return (
    <div data-idx={idx} style={{
      height: "100dvh",
      scrollSnapAlign: "start",
      scrollSnapStop: "always",
      position: "relative",
      background: "#000",
      overflow: "hidden",
      display: "flex", alignItems: "center", justifyContent: "center",
    }}>
      {/* Mount the video only for the active slide — one load at a time. */}
      {active && (
        <>
          <video
            ref={videoRef}
            src={video.shorts}
            loop={!autoplay}
            playsInline
            autoPlay
            muted={muted}
            preload="auto"
            onClick={onTap}
            onEnded={() => { if (autoplay && active && onAdvance) onAdvance(); }}
            style={{
              position: "relative",
              height: "100%",
          maxWidth: "min(100%, calc(100dvh * 9 / 16))",
          width: "auto",
          objectFit: "contain",
          background: "#000",
          zIndex: 1,
        }}
      />
        </>
      )}

      {/* Right side action rail — sits above the bottom info row */}
      <div style={{
        position: "absolute", right: "max(8px, calc((100% - min(100%, calc(100dvh * 9 / 16))) / 2 + 8px))",
        bottom: "calc(80px + env(safe-area-inset-bottom))", zIndex: 4,
        display: "flex", flexDirection: "column", gap: 14, alignItems: "center",
      }}>
        {video.psalm && (
          <FeedAction label={video.scripture || "Verse"} icon="📖" onClick={() => nav("bible", { book: "Psalms", chapter: video.psalm })} />
        )}
        <FeedAction label="Share" icon="↪" onClick={() => {
          if (navigator.share) navigator.share({ title: video.title, url: window.location.origin + window.location.pathname + "#shadow/song/" + video.id }).catch(() => {});
          else navigator.clipboard?.writeText(window.location.origin + window.location.pathname + "#shadow/song/" + video.id);
        }} />
      </div>

      {/* Info overlay — centered at top, below the close/mute bar */}
      <div style={{
        position: "absolute",
        left: 0, right: 0,
        top: "calc(70px + env(safe-area-inset-top))",
        padding: "0 24px",
        zIndex: 4,
        textAlign: "center",
        background: "transparent",
        pointerEvents: "none",
      }}>
        <h2 style={{
          fontFamily: "'Cinzel', serif", fontSize: 22, fontWeight: 500,
          margin: "0 0 6px", color: T.paper, letterSpacing: "0.02em", lineHeight: 1.2,
          textShadow: "0 1px 8px rgba(0,0,0,0.95), 0 0 16px rgba(0,0,0,0.7)",
        }}>{video.title}</h2>
        <div style={{
          fontSize: 14, color: T.paperDim, fontStyle: "italic",
          fontFamily: "'Cormorant Garamond', serif",
          textShadow: "0 1px 6px rgba(0,0,0,0.9)",
          pointerEvents: "auto",
        }}>
          {video.collectionTitle} · <a href={video.full} target="_blank" rel="noopener noreferrer" style={{ color: T.gold, fontStyle: "normal", textDecoration: "underline", textUnderlineOffset: "3px" }}>Full Video</a>
        </div>
      </div>
    </div>
  );
}

function FeedAction({ label, icon, onClick }) {
  return (
    <button onClick={onClick} aria-label={label} style={{
      width: 44, height: 44,
      background: "transparent", color: T.gold,
      border: "none", cursor: "pointer",
      display: "flex", alignItems: "center", justifyContent: "center",
      fontSize: 22, lineHeight: 1,
      textShadow: "0 1px 8px rgba(0,0,0,0.95), 0 0 12px rgba(0,0,0,0.7)",
    }}>
      {icon}
    </button>
  );
}

// Floating launcher button — appears on home + shadow pages
function FeedLaunchButton({ nav, label = "The Feed" }) {
  return (
    <button onClick={() => nav("feed")} style={{
      position: "fixed", right: 16, bottom: "calc(96px + env(safe-area-inset-bottom))",
      zIndex: 70,
      padding: "12px 18px",
      background: `linear-gradient(135deg, ${T.gold}, ${T.goldDeep})`,
      color: T.ink, border: "none",
      borderRadius: 28,
      cursor: "pointer",
      fontFamily: "'Cinzel', serif", fontSize: 11, letterSpacing: "0.24em",
      textTransform: "uppercase", fontWeight: 700,
      boxShadow: `0 8px 24px rgba(0,0,0,0.5), 0 0 24px ${T.gold}55`,
      display: "flex", alignItems: "center", gap: 8,
    }}>
      <svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor">
        <path d="M3 1v14l5-3 5 3V1H3z" />
      </svg>
      {label}
    </button>
  );
}

Object.assign(window, { VideoFeedPage, FeedSlide, FeedLaunchButton });
