// Galleria — Instagram-style grid with lightbox (expand, swipe, close).
// Add new photos by appending objects to GALLERY_ITEMS below.

const GALLERY_ITEMS = [
  // ── NUDE ─────────────────────────────────────────────
  { src: "assets/gallery/nude-01.jpg", tag: "Nude", caption: "milky white · dettaglio nero" },
  { src: "assets/gallery/nude-02.jpg", tag: "Nude", caption: "white shimmer · marble foil" },
  { src: "assets/gallery/nude-03.jpg", tag: "Nude", caption: "rosa latte · foglia oro accent" },
  { src: "assets/gallery/nude-04.jpg", tag: "Nude", caption: "baby boomer · shimmer" },
  { src: "assets/gallery/nude-05.jpg", tag: "Nude", caption: "rosa polka · farfalla swarovski" },

  // ── FRENCH ───────────────────────────────────────────
  { src: "assets/gallery/french-01.jpg", tag: "French", caption: "tortoise tip · finger nero" },
  { src: "assets/gallery/french-02.jpg", tag: "French", caption: "rosa baby · glitter tip" },
  { src: "assets/gallery/french-03.jpg", tag: "French", caption: "french bianca · arco swarovski" },
  { src: "assets/gallery/french-04.jpg", tag: "French", caption: "french milky · butterfly art" },
  { src: "assets/gallery/french-05.jpg", tag: "French", caption: "french bianca · fiore blu" },

  // ── GLOW ─────────────────────────────────────────────
  { src: "assets/gallery/glow-01.jpg", tag: "Glow", caption: "tropical mix · 3D starfish" },
  { src: "assets/gallery/glow-02.jpg", tag: "Glow", caption: "burgundy · cuori swarovski" },
  { src: "assets/gallery/glow-03.jpg", tag: "Glow", caption: "polka tips · floral art" },
  { src: "assets/gallery/glow-04.jpg", tag: "Glow", caption: "blueberry · french polka" },
  { src: "assets/gallery/glow-05.jpg", tag: "Glow", caption: "french rosa · close up" },
  { src: "assets/gallery/glow-06.jpg", tag: "Glow", caption: "rosa & glitter · fiocco 3D" },

  // ── GLITTER ──────────────────────────────────────────
  { src: "assets/gallery/glitter-01.jpg", tag: "Glitter", caption: "rosa cipria · fiocco 3D" },
  { src: "assets/gallery/glitter-02.jpg", tag: "Glitter", caption: "fucsia · cuore swarovski" },
  { src: "assets/gallery/glitter-03.jpg", tag: "Glitter", caption: "acqua marina · effetto ghiaccio" },
  { src: "assets/gallery/glitter-04.jpg", tag: "Glitter", caption: "pink shock · foglia oro" },

  // ── FLOREAL ──────────────────────────────────────────
  { src: "assets/gallery/floral-01.jpg", tag: "Floreal", caption: "fucsia shimmer · campo fiorito" },
  { src: "assets/gallery/floral-02.jpg", tag: "Floreal", caption: "nude · margheritine" },
  { src: "assets/gallery/floral-03.jpg", tag: "Floreal", caption: "rosso ciliegia · fiore bianco" },
  { src: "assets/gallery/floral-04.jpg", tag: "Floreal", caption: "lilla · fiori viola" },
  { src: "assets/gallery/floral-05.jpg", tag: "Floreal", caption: "french fucsia · fiore tropicale" },
  { src: "assets/gallery/floral-06.jpg", tag: "Floreal", caption: "french azzurra · fiore swarovski" },

  // ── CHROME ───────────────────────────────────────────
  { src: "assets/gallery/chrome-01.jpg", tag: "Chrome", caption: "red chrome · cuori accent" },

  // ── NAIL ART ─────────────────────────────────────────
  { src: "assets/gallery/nailart-01.jpg", tag: "Nail Art", caption: "blu galassia · cat eye" },
  { src: "assets/gallery/nailart-02.jpg", tag: "Nail Art", caption: "ombré rosa-azzurro · swarovski" },
  { src: "assets/gallery/nailart-03.jpg", tag: "Nail Art", caption: "pearl · margherite 3D" },

  // ── PERLÈ ────────────────────────────────────────────
  { src: "assets/gallery/perle-01.jpg", tag: "Perlè", caption: "rosa · fiocco 3D · perline argento" },

  // ── ALMOND ───────────────────────────────────────────
  { src: "assets/gallery/almond-01.jpg", tag: "Almond", caption: "rosa shimmer · fiore bianco" },
  { src: "assets/gallery/almond-02.jpg", tag: "Almond", caption: "polka mix · nero & bianco" },
  { src: "assets/gallery/almond-03.jpg", tag: "Almond", caption: "french classica · short almond" },
  { src: "assets/gallery/almond-04.jpg", tag: "Almond", caption: "candy cane · christmas vibes" },

  // ── RED ──────────────────────────────────────────────
  { src: "assets/gallery/red-01.jpg", tag: "Red", caption: "rosso lacca · fiocco oro & perla" },

  // ── ANIMALIER ────────────────────────────────────────
  { src: "assets/gallery/animalier-01.jpg", tag: "Animalier", caption: "leopard · swarovski accent" },

  // ── LILLA ────────────────────────────────────────────
  { src: "assets/gallery/lilla-01.jpg", tag: "Lilla", caption: "ombré bianco → lilla" },
  { src: "assets/gallery/lilla-02.jpg", tag: "Lilla", caption: "lavanda · floral art & glitter" },
];

// Photo-fit defaults to "cover" but can be overridden per-item: { fit: "contain" }
// orientation auto-detected — we just rely on object-fit: cover with center.

function PlaceholderBg({ idx }) {
  const hue = (idx * 27) % 360;
  return {
    background: `linear-gradient(${135 + idx * 13}deg,
      hsl(${340 + (hue % 30)}, 65%, 78%) 0%,
      hsl(${320 + (hue % 40)}, 60%, 70%) 60%,
      hsl(${300 + (hue % 30)}, 50%, 60%) 100%)`,
  };
}

function GalleryTile({ item, idx, onOpen }) {
  return (
    <button className="gtile" onClick={() => onOpen(idx)} aria-label={item.tag}>
      {item.src ? (
        <img className="gtile-img" src={item.src} alt={item.caption || item.tag} loading="lazy" />
      ) : (
        <div className="gtile-img" style={PlaceholderBg({ idx })}>
          <div className="gtile-shine"></div>
        </div>
      )}
      <div className="gtile-hover">
        <span className="script">{item.tag}</span>
        <small>{item.caption}</small>
      </div>
    </button>
  );
}

function Lightbox({ openIndex, items, onClose, onPrev, onNext }) {
  const isOpen = openIndex !== null;
  React.useEffect(() => {
    if (!isOpen) return;
    const onKey = (e) => {
      if (e.key === "Escape") onClose();
      if (e.key === "ArrowLeft") onPrev();
      if (e.key === "ArrowRight") onNext();
    };
    document.addEventListener("keydown", onKey);
    document.body.style.overflow = "hidden";
    return () => {
      document.removeEventListener("keydown", onKey);
      document.body.style.overflow = "";
    };
  }, [isOpen, onClose, onPrev, onNext]);

  const touchRef = React.useRef({ x: 0, t: 0 });
  const onTS = (e) => { touchRef.current = { x: e.touches[0].clientX, t: Date.now() }; };
  const onTE = (e) => {
    const dx = e.changedTouches[0].clientX - touchRef.current.x;
    if (Math.abs(dx) > 50) dx < 0 ? onNext() : onPrev();
  };

  if (!isOpen) return null;
  const item = items[openIndex];

  return (
    <div className="lightbox" onClick={onClose}>
      <div className="lightbox-bg"></div>
      <button className="lb-close" onClick={onClose} aria-label="Chiudi">×</button>
      {items.length > 1 && (
        <React.Fragment>
          <button className="lb-prev" onClick={(e) => { e.stopPropagation(); onPrev(); }} aria-label="Precedente">‹</button>
          <button className="lb-next" onClick={(e) => { e.stopPropagation(); onNext(); }} aria-label="Successivo">›</button>
        </React.Fragment>
      )}
      <div className="lb-stage" onClick={(e) => e.stopPropagation()} onTouchStart={onTS} onTouchEnd={onTE}>
        <div className="lb-card glass liquid">
          <div className="lb-photo">
            {item.src
              ? <img src={item.src} alt={item.caption || item.tag} />
              : <div className="lb-photo-fallback" style={PlaceholderBg({ idx: openIndex })}><div className="gtile-shine"></div></div>}
          </div>
          <div className="lb-meta">
            <div>
              <div className="eyebrow" style={{ marginBottom: 8 }}>lavoro #{String(openIndex + 1).padStart(2, "0")}</div>
              <h3 className="script lb-tag">{item.tag}</h3>
              <p className="muted" style={{ margin: "4px 0 0" }}>{item.caption}</p>
            </div>
            <div className="lb-actions">
              <a href={`https://wa.me/393465748855?text=Ciao%20Ewa,%20mi%20interessa%20il%20lavoro%20n.${openIndex + 1}%20(${encodeURIComponent(item.tag)})`} target="_blank" rel="noreferrer" className="btn btn-primary">Voglio questo</a>
              <a href="contatti.html#prenota" className="btn btn-glass">Prenota appuntamento</a>
            </div>
          </div>
        </div>
        <div className="lb-counter">{openIndex + 1} / {items.length}</div>
      </div>
    </div>
  );
}

function FilterDropdown({ tags, filter, setFilter }) {
  const [open, setOpen] = React.useState(false);
  const wrapRef = React.useRef(null);

  React.useEffect(() => {
    if (!open) return;
    const onDoc = (e) => {
      if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
    };
    const onKey = (e) => { if (e.key === "Escape") setOpen(false); };
    document.addEventListener("mousedown", onDoc);
    document.addEventListener("touchstart", onDoc);
    document.addEventListener("keydown", onKey);
    return () => {
      document.removeEventListener("mousedown", onDoc);
      document.removeEventListener("touchstart", onDoc);
      document.removeEventListener("keydown", onKey);
    };
  }, [open]);

  return (
    <div className={"filter-dd" + (open ? " open" : "")} ref={wrapRef}>
      <button className="filter-dd-trigger" onClick={() => setOpen(o => !o)} aria-expanded={open}>
        <span className="filter-dd-label">
          <span className="filter-dd-kicker">Categoria</span>
          <b>{filter}</b>
        </span>
        <span className="filter-dd-chev" aria-hidden>▾</span>
      </button>
      <div className="filter-dd-menu" role="listbox" aria-hidden={!open}>
        {tags.map(t => (
          <button
            key={t}
            role="option"
            aria-selected={filter === t}
            className={"filter-dd-opt" + (filter === t ? " active" : "")}
            onClick={() => { setFilter(t); setOpen(false); }}
          >
            <span>{t}</span>
            {filter === t && <span className="filter-dd-check" aria-hidden>✓</span>}
          </button>
        ))}
      </div>
    </div>
  );
}

function GalleriaApp() {
  useReveal();
  const [filter, setFilter] = React.useState("Tutti");
  const [openIndex, setOpenIndex] = React.useState(null);
  const [visibleCount, setVisibleCount] = React.useState(9);
  const sentinelRef = React.useRef(null);

  // Tags computed from actual data, with "Tutti" first.
  const tags = React.useMemo(() => {
    const set = new Set();
    GALLERY_ITEMS.forEach(i => set.add(i.tag));
    return ["Tutti", ...Array.from(set)];
  }, []);

  // Fisher–Yates shuffle (returns new array, doesn't mutate input).
  const shuffle = (arr) => {
    const a = arr.slice();
    for (let i = a.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [a[i], a[j]] = [a[j], a[i]];
    }
    return a;
  };

  // Filtered + (shuffled when "Tutti"). Reshuffles only when filter switches to Tutti.
  const filtered = React.useMemo(() => {
    if (filter === "Tutti") return shuffle(GALLERY_ITEMS);
    return GALLERY_ITEMS.filter(i => i.tag === filter);
  }, [filter]);

  // Reset visible count whenever filter changes.
  React.useEffect(() => {
    setVisibleCount(9);
  }, [filter]);

  // IntersectionObserver on sentinel — load more when it scrolls into view.
  React.useEffect(() => {
    if (!sentinelRef.current) return;
    if (visibleCount >= filtered.length) return;
    const io = new IntersectionObserver((entries) => {
      if (entries[0].isIntersecting) {
        // Small delay so user actually sees the loader on fast scrolls.
        setTimeout(() => setVisibleCount(c => Math.min(c + 6, filtered.length)), 250);
      }
    }, { rootMargin: "300px 0px" });
    io.observe(sentinelRef.current);
    return () => io.disconnect();
  }, [visibleCount, filtered.length]);

  const visible = filtered.slice(0, visibleCount);
  const hasMore = visibleCount < filtered.length;

  const onOpen = (idx) => setOpenIndex(idx);
  const onPrev = () => setOpenIndex(i => (i - 1 + visible.length) % visible.length);
  const onNext = () => setOpenIndex(i => (i + 1) % visible.length);

  return (
    <React.Fragment>
      <Blobs />
      <Nav active="Galleria" />
      <header className="page-head">
        <div className="shell">
          <div className="reveal" style={{ textAlign: "center" }}>
            <div className="eyebrow">galleria</div>
            <h1 className="page-title">I <em className="script">lavori</em>.</h1>
            <p className="muted page-sub">Tocca una foto per vederla in grande. Scorri ←/→ per cambiare.</p>
          </div>
          {tags.length > 2 && (
            <React.Fragment>
              <div className="filters reveal">
                {tags.map(t => (
                  <button key={t} className={"filter-pill " + (filter === t ? "active" : "")}
                          onClick={() => { setFilter(t); setOpenIndex(null); }}>{t}</button>
                ))}
              </div>
              <div className="filters-mobile reveal">
                <FilterDropdown
                  tags={tags}
                  filter={filter}
                  setFilter={(t) => { setFilter(t); setOpenIndex(null); }}
                />
              </div>
            </React.Fragment>
          )}
        </div>
      </header>
      <section className="section-sm" style={{ paddingTop: 24 }}>
        <div className="shell">
          <div className="ig-grid">
            {visible.map((item, idx) => (
              <GalleryTile key={item.src || idx} item={item} idx={idx} onOpen={onOpen} />
            ))}
            {hasMore && <div ref={sentinelRef} className="ig-sentinel"></div>}
          </div>
          {hasMore && (
            <div className="ig-loading">
              <span className="dot"></span><span className="dot"></span><span className="dot"></span>
              <span style={{ marginLeft: 6 }}>caricamento…</span>
            </div>
          )}
        </div>
      </section>
      <Lightbox openIndex={openIndex} items={visible} onClose={() => setOpenIndex(null)} onPrev={onPrev} onNext={onNext} />
      <Footer />
      <EwaTweaks />
    </React.Fragment>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<GalleriaApp />);
