/* Gallery.jsx — Spring Arts Showcase 4/28/26 photo gallery.
   Photos are read from /img/manifest.json at runtime. Regenerate the manifest
   after dropping new photos into /img by running tools/build-gallery-manifest.js. */

// CR #195: show 25 photos initially with a "See more" toggle to load the rest.
const GALLERY_PREVIEW_COUNT = 25;

function GalleryPage() {
  const [items, setItems] = React.useState([]);
  const [filter, setFilter] = React.useState("all");
  const [lightbox, setLightbox] = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState("");
  const [expanded, setExpanded] = React.useState(false);

  React.useEffect(() => {
    let cancelled = false;
    fetch("/img/manifest.json")
      .then(r => r.ok ? r.json() : Promise.reject(new Error(`status_${r.status}`)))
      .then(j => { if (!cancelled) setItems(j.items || []); })
      .catch(e => { if (!cancelled) setError(String(e.message || e)); })
      .finally(() => { if (!cancelled) setLoading(false); });
    return () => { cancelled = true; };
  }, []);

  // Spread heights/widths in a deterministic way so masonry doesn't reshuffle.
  const sized = React.useMemo(() => items.map((it, i) => {
    const pattern = [
      { w: 2, h: 1 }, { w: 1, h: 1 }, { w: 1, h: 1 }, { w: 1, h: 2 },
      { w: 2, h: 1 }, { w: 1, h: 1 }, { w: 1, h: 1 }, { w: 2, h: 1 },
      { w: 1, h: 1 }, { w: 1, h: 2 }, { w: 1, h: 1 }, { w: 2, h: 1 }
    ];
    const p = pattern[i % pattern.length];
    return { ...it, w: p.w, h: p.h };
  }), [items]);

  const filtered = filter === "all" ? sized : sized.filter(i => i.cat === filter);

  const cats = [
    { id: "all", label: "All photos" },
    { id: "showcase", label: "Spring Showcase" }
  ];

  const driveUrl = (window.useCMS ? window.useCMS("showcase.drive_url", "") : "");
  // showcase.video_ids: comma-separated. Bare token = YouTube ID. "drive:<file_id>" = Google Drive video.
  const VIDEO_DEFAULT = "g8_1641gADQ,i1fxYlFdB_Y";
  const videoIds = (window.useCMS ? window.useCMS("showcase.video_ids", VIDEO_DEFAULT) : VIDEO_DEFAULT);
  const videos = String(videoIds || "").split(",").map(s => s.trim()).filter(Boolean).map(raw => {
    if (raw.startsWith("drive:")) {
      const id = raw.slice(6);
      return { kind: "drive", id, src: `https://drive.google.com/file/d/${id}/preview` };
    }
    return { kind: "youtube", id: raw, src: `https://www.youtube-nocookie.com/embed/${raw}?rel=0&modestbranding=1` };
  });

  return (
    <div>
      <section style={{ background: "var(--c-plum)", color: "var(--c-cream)", padding: "80px 0 64px", borderBottom: "2px solid var(--c-ink)" }}>
        <div className="container">
          <div className="eyebrow" style={{ color: "var(--c-accent)" }}>04 · 28 · 2026 · Venice Island PAC</div>
          <h1 className="display" style={{ fontSize: "clamp(48px, 9vw, 132px)", color: "var(--c-cream)", margin: "12px 0 18px", lineHeight: 0.95 }}>
            Spring Arts<br />Showcase.
          </h1>
          <p style={{ fontSize: 19, maxWidth: 640, opacity: 0.9, lineHeight: 1.5 }}>
            One night, 12 rec centers, 100+ young performers. Highlights from
            our spring 2026 showcase at Venice Island Performing Arts Center.
          </p>
          <div style={{ display: "flex", gap: 28, marginTop: 32, flexWrap: "wrap" }}>
            <SmallStat n={items.length || "—"} label="Photos" />
            <SmallStat n="100+" label="Performers" />
            <SmallStat n="24" label="Acts" />
            <SmallStat n="12" label="Rec centers" />
          </div>
        </div>
      </section>

      <section className="section">
        <div className="container">
          <div style={{ display: "flex", gap: 8, marginBottom: 28, flexWrap: "wrap", alignItems: "center", justifyContent: "space-between" }}>
            <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
              {cats.map(c => (
                <button
                  key={c.id}
                  onClick={() => setFilter(c.id)}
                  className="btn small"
                  style={{
                    background: filter === c.id ? "var(--c-ink)" : "var(--c-paper)",
                    color: filter === c.id ? "var(--c-paper)" : "var(--c-ink)",
                  }}
                >
                  {c.label}
                </button>
              ))}
            </div>
            <div style={{ fontFamily: "var(--f-mono)", fontSize: 11, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--c-ink-soft)" }}>
              {filtered.length} photos
            </div>
          </div>

          {loading && <div style={{ padding: 60, textAlign: "center", color: "var(--c-ink-soft)" }}>Loading photos…</div>}
          {error && !loading && <div style={{ padding: 60, textAlign: "center", color: "var(--c-primary-deep)" }}>Couldn't load photo manifest. ({error})</div>}
          {!loading && !error && filtered.length === 0 && <div style={{ padding: 60, textAlign: "center", color: "var(--c-ink-soft)" }}>No photos yet — drop them in /img and rebuild the manifest.</div>}

          {filtered.length > 0 && (() => {
            const hasMore = filtered.length > GALLERY_PREVIEW_COUNT;
            const visible = (hasMore && !expanded) ? filtered.slice(0, GALLERY_PREVIEW_COUNT) : filtered;
            const hiddenCount = filtered.length - GALLERY_PREVIEW_COUNT;
            return (
              <>
                <div style={{
                  display: "grid",
                  gridTemplateColumns: "repeat(4, 1fr)",
                  gridAutoRows: "180px",
                  gap: 14,
                }} className="masonry">
                  {visible.map((item) => (
                    <button
                      key={item.src}
                      onClick={() => setLightbox(item)}
                      aria-label={`Open ${item.alt}`}
                      style={{
                        gridColumn: `span ${item.w}`,
                        gridRow: `span ${item.h}`,
                        cursor: "pointer",
                        borderRadius: 14,
                        border: "2px solid var(--c-ink)",
                        overflow: "hidden",
                        padding: 0,
                        background: "var(--c-cream-deep)",
                        transition: "transform 150ms",
                      }}
                      onMouseEnter={(e) => e.currentTarget.style.transform = "translate(-3px, -3px)"}
                      onMouseLeave={(e) => e.currentTarget.style.transform = "translate(0, 0)"}
                    >
                      <img src={item.src} alt={item.alt} loading="lazy"
                        style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }} />
                    </button>
                  ))}
                </div>
                {hasMore && (
                  <div style={{ display: "flex", justifyContent: "center", marginTop: 28 }}>
                    <button
                      type="button"
                      onClick={() => setExpanded(v => !v)}
                      aria-expanded={expanded}
                      className="btn small"
                      style={{ background: "var(--c-ink)", color: "var(--c-paper)" }}
                    >
                      {expanded
                        ? <>Show fewer <span aria-hidden="true">↑</span></>
                        : <>See {hiddenCount} more {hiddenCount === 1 ? "photo" : "photos"} <span aria-hidden="true">↓</span></>}
                    </button>
                  </div>
                )}
              </>
            );
          })()}

          {driveUrl && (
            <div style={{ marginTop: 40, padding: 24, border: "2px solid var(--c-ink)", borderRadius: 18, background: "var(--c-cream-deep)", display: "flex", justifyContent: "space-between", alignItems: "center", gap: 14, flexWrap: "wrap" }}>
              <div>
                <div className="eyebrow">Source archive</div>
                <div className="display" style={{ fontSize: 22, marginTop: 4 }}>Venice Island — 4/28/26 Show</div>
                <div style={{ fontSize: 13, color: "var(--c-ink-soft)", marginTop: 4 }}>Full Google Drive folder with all photos and B-roll video.</div>
              </div>
              <a href={driveUrl} target="_blank" rel="noopener" className="btn small ochre">Open Drive folder ↗</a>
            </div>
          )}

          <FlickrAlbumCard />
          <PhotographerCredit />
        </div>

        <style>{`
          @media (max-width: 980px) { .masonry { grid-template-columns: repeat(3, 1fr) !important; } }
          @media (max-width: 700px) { .masonry { grid-template-columns: repeat(2, 1fr) !important; grid-auto-rows: 140px !important; } }
        `}</style>
      </section>

      {videos.length > 0 && (
        <section style={{ background: "var(--c-paper)", borderTop: "2px solid var(--c-ink)", borderBottom: "2px solid var(--c-ink)", padding: "64px 0" }}>
          <div className="container">
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end", marginBottom: 24, flexWrap: "wrap", gap: 16 }}>
              <div>
                <div className="eyebrow">Watch the showcase</div>
                <div className="display" style={{ fontSize: "clamp(32px, 4.5vw, 56px)", marginTop: 10, lineHeight: 0.98 }}>
                  Past PPR shows on film.
                </div>
                <p style={{ fontSize: 16, color: "var(--c-ink-soft)", marginTop: 12, maxWidth: 640, lineHeight: 1.55 }}>
                  Cobbs Creek 2025 Intro Camp Performance of Beauty and the Beast,
                  and Myers 2024 Intro Camp Performance of High School Musical.
                  These are the kinds of nights our young performers build toward across the summer.
                </p>
              </div>
            </div>
            <div style={{ display: "grid", gridTemplateColumns: "repeat(2, 1fr)", gap: 20 }} className="video-grid">
              {videos.map(v => (
                <div key={v.id} style={{
                  aspectRatio: "16 / 9", border: "2px solid var(--c-ink)", borderRadius: 14,
                  overflow: "hidden", background: "var(--c-cream-deep)"
                }}>
                  <iframe
                    src={v.src}
                    title={`PPR Performing Arts showcase video ${v.id}`}
                    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
                    referrerPolicy="strict-origin-when-cross-origin"
                    allowFullScreen
                    loading="lazy"
                    style={{ width: "100%", height: "100%", border: 0, display: "block" }}
                  />
                </div>
              ))}
            </div>
            <style>{`
              @media (max-width: 800px) { .video-grid { grid-template-columns: 1fr !important; } }
            `}</style>
          </div>
        </section>
      )}

      {/* CR #273: Star Players of Philadelphia -- pinned section at the bottom
          of the gallery. Bill Arthur (Holmesburg) runs the group; the link
          target is the section's #star-players anchor (cross-linked from his
          committee bio panel on /#about). */}
      <section
        id="star-players"
        style={{
          background: "var(--c-cream-deep)",
          borderTop: "2px solid var(--c-ink)",
          borderBottom: "2px solid var(--c-ink)",
          padding: "72px 0",
          scrollMarginTop: 88,
        }}
      >
        <div className="container">
          <div style={{ maxWidth: 760 }}>
            <div className="eyebrow" style={{ color: "var(--c-primary-deep)" }}>Spotlight</div>
            <div className="display" style={{ fontSize: "clamp(32px, 4.5vw, 56px)", marginTop: 10, lineHeight: 1 }}>
              Star Players of Philadelphia.
            </div>
            <p style={{ fontSize: 16.5, color: "var(--c-ink-soft)", marginTop: 18, lineHeight: 1.65 }}>
              Founded in 2013, the Star Players are a theater arts group for the
              Philadelphia Parks &amp; Recreation community. Their mission is to
              bring cultural activities to children and adults of every background
              through creative expression &mdash; giving participants the chance to
              perform in front of a real audience and showcase their talents.
            </p>
            <p style={{ fontSize: 16.5, color: "var(--c-ink-soft)", marginTop: 14, lineHeight: 1.65 }}>
              The group develops acting, singing, and dancing skills through hands-on
              instruction, and runs alongside the broader PPR programming calendar.
              Group activities include productions of musicals, dramas, comedies,
              and cabarets, plus special classes and workshops throughout the year.
            </p>
          </div>

          <div className="star-players-grid" style={{ marginTop: 36 }}>
            {[
              { src: "/img/star-players-cast.jpg",   alt: "Star Players cast on stage" },
              { src: "/img/star-players-dance.jpg",  alt: "Star Players dance number in performance" },
              { src: "/img/star-players-awards.jpg", alt: "Star Players annual awards dinner" },
              { src: "/img/star-players-screen.jpg", alt: "Star Players projection backdrop during a show" },
              { src: "/img/star-players-bazaar.jpg", alt: "Star Players choir performing at the community bazaar" },
              { src: "/img/star-players-santa.jpg",  alt: "Star Players choir at Breakfast with Santa" },
              { src: "/img/star-players-step.jpg",   alt: "Star Players performing Step in Time" },
            ].map((p) => (
              <button
                key={p.src}
                type="button"
                onClick={() => setLightbox(p)}
                style={{
                  appearance: "none",
                  padding: 0,
                  border: "2px solid var(--c-ink)",
                  borderRadius: 14,
                  overflow: "hidden",
                  background: "var(--c-paper)",
                  cursor: "zoom-in",
                  aspectRatio: "4 / 3",
                  boxShadow: "var(--shadow-lift)",
                }}
              >
                <img
                  src={p.src}
                  alt={p.alt}
                  loading="lazy"
                  style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }}
                />
              </button>
            ))}
          </div>

          <div
            className="star-players-contact"
            style={{
              marginTop: 36,
              padding: 24,
              border: "2px solid var(--c-ink)",
              borderRadius: 18,
              background: "var(--c-paper)",
              display: "grid",
              gridTemplateColumns: "1fr 1fr",
              gap: 20,
              boxShadow: "var(--shadow-lift)",
            }}
          >
            <div>
              <div className="eyebrow">Home base</div>
              <div style={{ fontSize: 17, fontWeight: 600, marginTop: 8 }}>Holmesburg Recreation Center</div>
              <a
                href="tel:2156858714"
                style={{ display: "inline-block", marginTop: 10, color: "var(--c-primary-deep)", fontWeight: 600, fontSize: 16 }}
              >
                215-685-8714
              </a>
              <div style={{ fontSize: 11.5, color: "var(--c-ink-soft)", marginTop: 4, fontFamily: "var(--f-mono)", letterSpacing: "0.05em" }}>
                Holmesburg direct line
              </div>
            </div>
            <div>
              <div className="eyebrow">Get involved</div>
              <a
                href="mailto:Bill.arthur@phila.gov"
                style={{ display: "block", marginTop: 8, color: "var(--c-ink)", fontWeight: 600 }}
              >
                Bill.arthur@phila.gov
              </a>
              <a
                href="https://www.facebook.com/starplayersPPR/"
                target="_blank"
                rel="noopener"
                className="btn small ghost"
                style={{ marginTop: 14, display: "inline-flex", alignItems: "center", gap: 8 }}
              >
                Star Players on Facebook ↗
              </a>
            </div>
          </div>

          <style>{`
            .star-players-grid {
              display: grid;
              grid-template-columns: repeat(4, 1fr);
              gap: 16px;
            }
            @media (max-width: 900px) {
              .star-players-grid { grid-template-columns: repeat(2, 1fr); }
              .star-players-contact { grid-template-columns: 1fr !important; }
            }
          `}</style>
        </div>
      </section>

      {lightbox && (
        <div
          onClick={() => setLightbox(null)}
          style={{ position: "fixed", inset: 0, background: "rgba(42,24,32,0.92)", zIndex: 100, display: "flex", alignItems: "center", justifyContent: "center", padding: 32, cursor: "zoom-out" }}
        >
          <img src={lightbox.src} alt={lightbox.alt}
            onClick={(e) => e.stopPropagation()}
            style={{ width: "min(1100px, 92vw)", maxHeight: "88vh", objectFit: "contain", borderRadius: 12, border: "2px solid var(--c-paper)" }} />
          <button onClick={() => setLightbox(null)} aria-label="Close" style={{
            position: "absolute", top: 24, right: 24, background: "var(--c-paper)",
            border: "2px solid var(--c-ink)", borderRadius: 999,
            width: 44, height: 44, fontSize: 20, fontWeight: 800, cursor: "pointer",
          }}>×</button>
        </div>
      )}
    </div>
  );
}

function SmallStat({ n, label }) {
  return (
    <div>
      <div className="display" style={{ fontSize: 36, color: "var(--c-accent)", lineHeight: 1 }}>{n}</div>
      <div style={{ fontFamily: "var(--f-mono)", fontSize: 11, letterSpacing: "0.12em", textTransform: "uppercase", marginTop: 4, opacity: 0.7 }}>{label}</div>
    </div>
  );
}

function FlickrAlbumCard() {
  return (
    <div style={{
      marginTop: 40,
      padding: 24,
      border: "2px solid var(--c-ink)",
      borderRadius: 18,
      background: "var(--c-paper)",
      display: "flex",
      justifyContent: "space-between",
      alignItems: "center",
      gap: 14,
      flexWrap: "wrap",
    }}>
      <div>
        <div className="eyebrow">More photos</div>
        <div className="display" style={{ fontSize: 22, marginTop: 4 }}>
          City Wide Dance Festival &mdash; 4/25/2024
        </div>
        <div style={{ fontSize: 13, color: "var(--c-ink-soft)", marginTop: 4 }}>
          Full album from the Citywide Dance Festival at Venice Island PAC,
          hosted on Flickr.
        </div>
      </div>
      <a
        href="https://www.flickr.com/photos/77365596@N05/albums/72177720316587384/"
        target="_blank"
        rel="noopener"
        className="btn small ochre"
      >
        Open Flickr album ↗
      </a>
    </div>
  );
}

function PhotographerCredit() {
  return (
    <div style={{
      marginTop: 40,
      padding: 28,
      border: "2px solid var(--c-ink)",
      borderRadius: 18,
      background: "var(--c-ink)",
      color: "var(--c-cream)",
      display: "flex",
      justifyContent: "space-between",
      alignItems: "center",
      gap: 18,
      flexWrap: "wrap",
    }}>
      <div style={{ flex: "1 1 320px", minWidth: 0 }}>
        <div className="eyebrow" style={{ color: "var(--c-accent)" }}>Photography by</div>
        <img
          src="/img/renzolution-logo.png"
          alt="Renzolution Photography"
          style={{ display: "block", maxWidth: 280, width: "100%", height: "auto", marginTop: 12 }}
          loading="lazy"
        />
        <p style={{ fontSize: 14, color: "rgba(251,243,226,0.78)", marginTop: 14, lineHeight: 1.55, maxWidth: 520 }}>
          Capturing PPR's new work this summer. For photography inquiries, follow
          along on Instagram or reach out by email.
        </p>
      </div>
      <div style={{ display: "flex", gap: 10, flexWrap: "wrap" }}>
        <a
          href="https://www.instagram.com/renzolutionnn"
          target="_blank"
          rel="noopener"
          className="btn small ochre"
        >
          @renzolutionnn ↗
        </a>
        <a
          href="mailto:renzolutionphotography@gmail.com"
          className="btn small ghost"
          style={{ color: "var(--c-cream)", borderColor: "var(--c-cream)" }}
        >
          Email →
        </a>
      </div>
    </div>
  );
}

Object.assign(window, { GalleryPage, PhotographerCredit, FlickrAlbumCard });
