// ABLY — Gallery (clean editorial mosaic + filters + lightbox)

const GAL_DIR = 'assets/gallery/';

// Curated, people-forward selection. Order within each category is best-first.
const GALLERY_DATA = {
  Celebrations: [
    { f: 'g075', cap: 'Champagne and cheers at Land\u2019s End' },
    { f: 'g000', cap: 'A toast to unforgettable days' },
    { f: 'g036', cap: 'Celebrations that spill into the afternoon' },
    { f: 'g048', cap: 'Bachelorette mornings on the water' },
    { f: 'g051', cap: 'Your favorite people, one perfect day' },
    { f: 'g086', cap: 'The whole crew, together on the water' },
    { f: 'g046', cap: 'Slow afternoons and good company' },
    { f: 'g058', cap: 'Raising a glass to the view' },
    { f: 'g027', cap: 'Family days made unforgettable' },
    { f: 'g070', cap: 'Sunshine, drinks and the open sea' },
    { f: 'g015', cap: 'Friends, hats and ocean breeze' },
    { f: 'g088', cap: 'Big energy at the Arch' },
  ],
  'Private Escapes': [
    { f: 'g014', cap: 'Just the two of you at the Arch' },
    { f: 'g089', cap: 'Floating the afternoon away' },
    { f: 'g054', cap: 'Private moments away from the crowds' },
    { f: 'g060', cap: 'Cooling off in hidden coves' },
    { f: 'g077', cap: 'The kind of day you\u2019ll wish lasted longer' },
    { f: 'g045', cap: 'Celebrate the moments that matter' },
    { f: 'g040', cap: 'Set sail, leave the rest behind' },
    { f: 'g037', cap: 'Quiet anchorages, all to yourself' },
    { f: 'g071', cap: 'Golden light and calm water' },
    { f: 'g067', cap: 'Easy days, warm water' },
    { f: 'g080', cap: 'Watching for whales from the deck' },
  ],
  'Luxury Moments': [
    { f: 'g042', cap: 'Sunset settles over the deck' },
    { f: 'g084', cap: 'Where every detail is taken care of' },
    { f: 'g055', cap: 'Evenings that feel effortless' },
    { f: 'g035', cap: 'Step inside the finer side of Cabo' },
    { f: 'g025', cap: 'Comfort, from bow to cabin' },
    { f: 'g002', cap: 'Warm wood and ocean air' },
    { f: 'g087', cap: 'Lounge, dine, repeat' },
    { f: 'g059', cap: 'Arrive in something extraordinary' },
    { f: 'g043', cap: 'A floating living room' },
    { f: 'g073', cap: 'Lines worth admiring' },
  ],
  'Cabo Views': [
    { f: 'g018', cap: 'The Arch at Land\u2019s End' },
    { f: 'g013', cap: 'When the whales come to say hello' },
    { f: 'g005', cap: 'Drifting beneath the cliffs' },
    { f: 'g029', cap: 'Turquoise water as far as you can see' },
    { f: 'g033', cap: 'Hidden coves along the coastline' },
    { f: 'g006', cap: 'Beaches only reachable by sea' },
    { f: 'g064', cap: 'The coastline from the water' },
    { f: 'g026', cap: 'Breaching giants off the coast' },
    { f: 'g074', cap: 'Iconic views, all day long' },
    { f: 'g009', cap: 'Anchored where the desert meets the sea' },
  ],
};

const GAL_CATEGORIES = ['Celebrations', 'Private Escapes', 'Luxury Moments', 'Cabo Views'];

// Tag each image with its category, then build a curated "Featured" mix.
const withCat = (cat) => GALLERY_DATA[cat].map((it) => ({ ...it, cat }));

const FEATURED_ORDER = [
  'g075', 'g014', 'g042', 'g018', 'g089', 'g036', // first 6 (default view)
  'g054', 'g084', 'g013', 'g048', 'g055', 'g005', 'g060', // revealed by "Show More"
];

const ALL_IMAGES = GAL_CATEGORIES.flatMap(withCat);
const byFile = Object.fromEntries(ALL_IMAGES.map((it) => [it.f, it]));
const FEATURED = FEATURED_ORDER.map((f) => byFile[f]).filter(Boolean);

const INITIAL_COUNT = 4;

// ---------------- Lightbox ----------------
const Lightbox = ({ items, index, onClose, onNav }) => {
  React.useEffect(() => {
    const onKey = (e) => {
      if (e.key === 'Escape') onClose();
      else if (e.key === 'ArrowRight') onNav(1);
      else if (e.key === 'ArrowLeft') onNav(-1);
    };
    window.addEventListener('keydown', onKey);
    document.body.style.overflow = 'hidden';
    return () => {
      window.removeEventListener('keydown', onKey);
      document.body.style.overflow = '';
    };
  }, [onClose, onNav]);

  if (index == null) return null;
  const item = items[index];

  // basic swipe support
  const touch = React.useRef(null);
  const onTouchStart = (e) => { touch.current = e.touches[0].clientX; };
  const onTouchEnd = (e) => {
    if (touch.current == null) return;
    const dx = e.changedTouches[0].clientX - touch.current;
    if (Math.abs(dx) > 50) onNav(dx < 0 ? 1 : -1);
    touch.current = null;
  };

  return (
    <div className="lb-overlay" onClick={onClose}>
      <button className="lb-close" onClick={onClose} aria-label="Close">
        <Icon name="x" size={22} stroke={1.8} />
      </button>
      <button className="lb-nav prev" onClick={(e) => { e.stopPropagation(); onNav(-1); }} aria-label="Previous">
        <Icon name="chevronLeft" size={26} stroke={1.8} />
      </button>
      <figure className="lb-figure" onClick={(e) => e.stopPropagation()} onTouchStart={onTouchStart} onTouchEnd={onTouchEnd}>
        <img src={(window.__resources && window.__resources[item.f]) || (GAL_DIR + item.f + '.avif')} alt={item.cap} />
        <figcaption className="lb-cap">
          <span className="lb-cap-cat">{item.cat}</span>
          {item.cap}
        </figcaption>
      </figure>
      <button className="lb-nav next" onClick={(e) => { e.stopPropagation(); onNav(1); }} aria-label="Next">
        <Icon name="chevronRight" size={26} stroke={1.8} />
      </button>
    </div>
  );
};

// ---------------- Gallery ----------------
const Gallery = () => {
  const isMobile = window.useIsMobile ? window.useIsMobile() : false;
  const [filter, setFilter] = React.useState('Featured');
  const [expanded, setExpanded] = React.useState(false);
  const [lightbox, setLightbox] = React.useState(null);

  const filters = ['Featured', ...GAL_CATEGORIES];

  const fullList = filter === 'Featured' ? FEATURED : withCat(filter);
  // Collapse to a few images on mobile only; desktop always shows the full set.
  const collapsed = isMobile && !expanded;
  const visible = collapsed ? fullList.slice(0, INITIAL_COUNT) : fullList;
  const canExpand = isMobile && fullList.length > INITIAL_COUNT;

  const selectFilter = (f) => {
    setFilter(f);
    setExpanded(false);
  };

  const openLightbox = (item) => {
    const idx = fullList.findIndex((x) => x.f === item.f);
    setLightbox(idx);
  };
  const nav = (dir) => {
    setLightbox((i) => {
      if (i == null) return i;
      const n = fullList.length;
      return (i + dir + n) % n;
    });
  };

  return (
    <section className="section-pad-sm gallery-section" id="gallery">
      <div className="container">
        <div className="gal-head reveal" style={{ maxWidth: 680 }}>
          <div className="eyebrow">Gallery</div>
          <h2 className="section-title" style={{ marginTop: 16 }}>See What Your Day in Cabo Could Look Like</h2>
          <p className="section-sub">From celebrations and sunset cruises to private escapes, explore the moments guests come to Cabo to experience.</p>
        </div>

        <div className="gal-filters-wrap reveal dl1">
          <span className="gal-filters-label">Filters</span>
          <div className="gal-filters" role="tablist" aria-label="Gallery filters">
            {filters.map((f) => (
              <button
                key={f}
                role="tab"
                aria-selected={filter === f}
                className={`gal-filter ${filter === f ? 'active' : ''}`}
                onClick={() => selectFilter(f)}
              >
                {f}
              </button>
            ))}
          </div>
        </div>

        <div className="gal-mosaic">
          {visible.map((item, i) => (
            <figure
              key={item.f}
              className="gal-m"
              style={{ animationDelay: `${Math.min(i, 8) * 40}ms` }}
              onClick={() => openLightbox(item)}
            >
              <img src={(window.__resources && window.__resources[item.f]) || (GAL_DIR + item.f + '.avif')} alt={item.cap} loading="lazy" />
              <figcaption className="gal-cap">
                {item.cap}
              </figcaption>
              <span className="gal-zoom"><Icon name="expand" size={16} stroke={1.8} /></span>
            </figure>
          ))}
        </div>

        <div className="gal-actions">
          {canExpand && !expanded && (
            <button className="btn btn-ghost-dark btn-sm" onClick={() => setExpanded(true)}>
              Show More
              <Icon name="plus" size={13} stroke={2} />
            </button>
          )}
          {canExpand && expanded && (
            <button className="btn btn-secondary btn-sm" onClick={() => setExpanded(false)}>
              Show Less
            </button>
          )}
          {(!isMobile || expanded || !canExpand) && (
            <a className="btn btn-ghost-dark btn-sm" href="/gallery">
              See Entire Gallery
              <Icon name="arrowRight" size={13} />
            </a>
          )}
        </div>
      </div>

      {lightbox != null && (
        <Lightbox items={fullList} index={lightbox} onClose={() => setLightbox(null)} onNav={nav} />
      )}
    </section>
  );
};

window.Gallery = Gallery;
