function GalleryPage({ navigate, openArtwork, addToCart }) {
  window.useSeo({
    title: "The Gallery · Larissa Fine Art — Original Oil Paintings for Sale",
    description: "Browse Larissa's full gallery of original oil paintings — Ontario landscapes, florals, still life and more. Each work is one-of-one and ships worldwide.",
    canonical: "https://larissaart.com/gallery",
  });
  const [cat, setCat] = useState("all");
  const [view, setView] = useState("masonry"); // masonry | grid
  const [sort, setSort] = useState("featured");

  const filtered = useMemo(() => {
    let list = cat === "all" ? window.PAINTINGS : window.PAINTINGS.filter((p) => p.category === cat);
    if (sort === "price-asc") list = [...list].sort((a, b) => a.price - b.price);
    if (sort === "price-desc") list = [...list].sort((a, b) => b.price - a.price);
    if (sort === "newest") list = [...list].sort((a, b) => b.year - a.year);
    return list;
  }, [cat, sort]);

  return (
    <div className="page-enter">
      {/* HERO BANNER */}
      <section style={{ paddingTop: 140, paddingBottom: 60, background: "var(--ivory)" }}>
        <div style={{ maxWidth: 1440, margin: "0 auto", padding: "0 40px" }}>
          <div className="eyebrow" style={{ color: "var(--gold-deep)" }}>The Gallery</div>
          <div style={{ display: "grid", gridTemplateColumns: "1.4fr 1fr", gap: 60, marginTop: 18, alignItems: "end" }}>
            <h1 className="h-display" style={{ fontSize: "clamp(56px, 7vw, 110px)", margin: 0 }}>
              <em style={{ fontStyle: "italic" }}>Every painting</em>,<br />
              one of one.
            </h1>
            <div style={{ paddingBottom: 18 }}>
              <p style={{ color: "var(--ink-soft)", fontSize: 16.5, lineHeight: 1.7, maxWidth: 460 }}>
                Explore a collection of hand-painted original oil works inspired by real places, light,
                and everyday beauty.
              </p>
            </div>
          </div>
        </div>
      </section>

      {/* FILTER BAR */}
      <div style={{
        position: "sticky", top: 78, zIndex: 50,
        background: "rgba(251,245,236,0.94)", backdropFilter: "blur(10px)",
        borderTop: "1px solid var(--line-soft)", borderBottom: "1px solid var(--line-soft)",
      }}>
        <div style={{ maxWidth: 1440, margin: "0 auto", padding: "16px 40px",
                      display: "flex", justifyContent: "space-between", alignItems: "center", gap: 24, flexWrap: "wrap" }}>
          <div style={{ display: "flex", gap: 4, flexWrap: "wrap" }}>
            {window.CATEGORIES.map((c) => (
              <button key={c.id} onClick={() => setCat(c.id)} style={{
                padding: "10px 18px",
                background: cat === c.id ? "var(--ink)" : "transparent",
                color: cat === c.id ? "var(--warm-white)" : "var(--ink)",
                border: "1px solid " + (cat === c.id ? "var(--ink)" : "var(--line)"),
                borderRadius: 999,
                fontSize: 12, letterSpacing: "0.12em", textTransform: "uppercase", fontWeight: 500,
                cursor: "pointer", transition: "all 200ms ease",
              }}>{c.label}</button>
            ))}
          </div>
          <div style={{ display: "flex", gap: 24, alignItems: "center" }}>
            <span style={{ fontSize: 11, color: "var(--ink-mute)", letterSpacing: "0.18em", textTransform: "uppercase" }}>
              {filtered.length} works
            </span>
            <select value={sort} onChange={(e) => setSort(e.target.value)} style={{
              background: "transparent", border: "1px solid var(--line)",
              padding: "8px 14px", borderRadius: 999,
              fontSize: 12, letterSpacing: "0.06em",
              color: "var(--ink)", cursor: "pointer", fontFamily: "var(--sans)",
            }}>
              <option value="featured">Sort · Featured</option>
              <option value="newest">Sort · Newest</option>
              <option value="price-asc">Sort · Price ↑</option>
              <option value="price-desc">Sort · Price ↓</option>
            </select>
            <div style={{ display: "flex", gap: 4 }}>
              <button onClick={() => setView("masonry")} title="Masonry" style={iconBtn(view === "masonry")}>
                <svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="1.4"><rect x="1" y="1" width="6" height="9" /><rect x="9" y="1" width="6" height="6" /><rect x="1" y="11" width="6" height="4" /><rect x="9" y="8" width="6" height="7" /></svg>
              </button>
              <button onClick={() => setView("grid")} title="Grid" style={iconBtn(view === "grid")}>
                <svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="1.4"><rect x="1" y="1" width="6" height="6" /><rect x="9" y="1" width="6" height="6" /><rect x="1" y="9" width="6" height="6" /><rect x="9" y="9" width="6" height="6" /></svg>
              </button>
            </div>
          </div>
        </div>
      </div>

      {/* GRID */}
      <section style={{ maxWidth: 1440, margin: "0 auto", padding: "60px 40px 40px" }}>
        {view === "masonry" ? (
          <MasonryView paintings={filtered} openArtwork={openArtwork} addToCart={addToCart} />
        ) : (
          <UniformGrid paintings={filtered} openArtwork={openArtwork} addToCart={addToCart} />
        )}
      </section>

      {/* FOOTER NOTE */}
      <section style={{ padding: "80px 40px", textAlign: "center", maxWidth: 800, margin: "0 auto" }}>
        <div className="h-script" style={{ fontSize: 44, color: "var(--gold-deep)" }}>
          Looking for something specific?
        </div>
        <p style={{ color: "var(--ink-soft)", marginTop: 14, fontSize: 16, lineHeight: 1.7 }}>
          I take a small number of commissions each year — most often lakeside scenes, family
          gardens, and pieces sized for a specific room. Write to me; I would love to hear.
        </p>
        <button className="btn btn-ghost" style={{ marginTop: 20 }} onClick={() => navigate("collector")}>
          Enquire About a Commission
        </button>
      </section>
    </div>
  );
}

function iconBtn(active) {
  return {
    width: 36, height: 36, borderRadius: 999,
    border: "1px solid " + (active ? "var(--ink)" : "var(--line)"),
    background: active ? "var(--ink)" : "transparent",
    color: active ? "var(--warm-white)" : "var(--ink)",
    cursor: "pointer", display: "inline-flex", alignItems: "center", justifyContent: "center",
  };
}

/* ============== Masonry View ============== */
function MasonryView({ paintings, openArtwork, addToCart }) {
  // 3-column masonry with height-balanced distribution: each painting is
  // assigned to the column currently shortest in *visual* height, so the
  // tail of the grid doesn't end up bunched in one column.
  const aspectByIndex = (p, i) => {
    const pool = ["4/5", "3/4", "1/1", "5/4", "3/5", "4/5"];
    return pool[i % pool.length];
  };
  const heightFactor = (aspect) => {
    const [w, h] = aspect.split("/").map(Number);
    return h / w; // taller cards push the column further down
  };
  const cols = [[], [], []];
  const colHeights = [0, 0, 0];
  paintings.forEach((p, i) => {
    const aspect = aspectByIndex(p, i);
    let shortest = 0;
    for (let j = 1; j < colHeights.length; j++) {
      if (colHeights[j] < colHeights[shortest]) shortest = j;
    }
    cols[shortest].push({ p, i });
    colHeights[shortest] += heightFactor(aspect) + 0.25; // 0.25 ≈ caption block
  });
  return (
    <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 28 }}>
      {cols.map((col, ci) => (
        <div key={ci} style={{ display: "flex", flexDirection: "column", gap: 28, paddingTop: ci === 1 ? 60 : 0 }}>
          {col.map(({ p, i }) => (
            <GalleryCard key={p.id} p={p} aspect={aspectByIndex(p, i)} openArtwork={openArtwork} addToCart={addToCart} />
          ))}
        </div>
      ))}
    </div>
  );
}

function UniformGrid({ paintings, openArtwork, addToCart }) {
  return (
    <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 32 }}>
      {paintings.map((p) => (
        <GalleryCard key={p.id} p={p} aspect="4/5" openArtwork={openArtwork} addToCart={addToCart} />
      ))}
    </div>
  );
}

function GalleryCard({ p, aspect, openArtwork, addToCart }) {
  const [hover, setHover] = useState(false);
  return (
    <article
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{ cursor: "pointer", display: "flex", flexDirection: "column" }}
      onClick={() => openArtwork(p.id)}
    >
      <div style={{ position: "relative", overflow: "hidden" }}>
        <Painting p={p} aspect={aspect} tag={false}
          style={{ transform: hover ? "scale(1.04)" : "scale(1)", transition: "transform 800ms cubic-bezier(.2,.7,.2,1)" }} />
        {/* hover overlay */}
        <div style={{
          position: "absolute", inset: 0,
          background: "linear-gradient(180deg, transparent 50%, rgba(46,42,36,0.55) 100%)",
          opacity: hover ? 1 : 0, transition: "opacity 320ms ease",
        }} />
        <div style={{
          position: "absolute", left: 22, right: 22, bottom: 22,
          color: "var(--warm-white)",
          transform: hover ? "translateY(0)" : "translateY(8px)",
          opacity: hover ? 1 : 0, transition: "all 280ms ease",
          fontSize: 13, lineHeight: 1.55,
        }}>
          {p.short}
        </div>
        <button
          onClick={(e) => { e.stopPropagation(); addToCart(p); }}
          style={{
            position: "absolute", top: 14, right: 14,
            background: "rgba(251,245,236,0.92)", border: "none",
            padding: "8px 14px", borderRadius: 999,
            fontSize: 11, letterSpacing: "0.18em", textTransform: "uppercase", fontWeight: 500,
            color: "var(--ink)", cursor: "pointer",
            transform: hover ? "translateY(0)" : "translateY(-4px)",
            opacity: hover ? 1 : 0,
            transition: "all 260ms ease", display: "inline-flex", alignItems: "center", gap: 6,
          }}
        >
          <Icon.Plus /> Acquire
        </button>
        {!p.available && <SoldBadge />}
      </div>
      <div style={{ marginTop: 16, display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: 14 }}>
        <div>
          <div style={{ fontFamily: "var(--serif)", fontSize: 21, lineHeight: 1.2 }}>{p.title}</div>
          <div style={{ fontSize: 11.5, color: "var(--ink-mute)", marginTop: 4, letterSpacing: "0.04em" }}>
            {p.dims} · {p.medium}
          </div>
        </div>
        <div style={{ textAlign: "right" }}>
          {p.available ? (
            <div style={{ fontFamily: "var(--serif)", fontSize: 18, color: "var(--ink)" }}>${p.price.toLocaleString()}</div>
          ) : (
            <div style={{ fontSize: 10.5, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--gold-deep)", fontWeight: 600 }}>Sold</div>
          )}
        </div>
      </div>
    </article>
  );
}

/* Big visible gold "SOLD" stamp on a painting card. */
function SoldBadge({ size = "normal" }) {
  const padY = size === "large" ? "10px" : "8px";
  const padX = size === "large" ? "22px" : "16px";
  const fontSize = size === "large" ? 16 : 13;
  return (
    <div style={{
      position: "absolute", top: 14, left: 14,
      background: "linear-gradient(135deg, #E5B048 0%, #C5A063 50%, #A7864A 100%)",
      color: "var(--warm-white)",
      padding: `${padY} ${padX}`,
      fontFamily: "var(--sans)",
      fontSize, letterSpacing: "0.32em", textTransform: "uppercase", fontWeight: 600,
      borderRadius: 4,
      boxShadow: "0 6px 14px -4px rgba(167,134,74,0.55), 0 1px 3px rgba(46,42,36,0.18)",
      transform: "rotate(-3deg)",
      zIndex: 3,
      pointerEvents: "none",
      textShadow: "0 1px 2px rgba(46,42,36,0.25)",
    }}>Sold</div>
  );
}

window.SoldBadge = SoldBadge;

window.GalleryPage = GalleryPage;
