// lux/gallery.jsx — responsive gallery grid, category filter, lightbox
// Requires: GALLERY_MANIFEST + GALLERY_CATEGORIES (gallery-data.js), AssetPlaceholder / useAssetExists (media.jsx)

const { useState, useEffect, useCallback, useMemo } = React;

const GALLERY_BASE = 'assets/gallery/';

function gallerySrc(file) {
  return GALLERY_BASE + file;
}

function GalleryThumb({ item, lang, onOpen }) {
  const src = gallerySrc(item.file);
  const exists = useAssetExists(src);
  const [imgFailed, setImgFailed] = useState(false);
  const alt = (item.alt && item.alt[lang]) || item.alt.pl || item.file;

  const showPlaceholder = exists === false || imgFailed;
  const probing = exists === null && !imgFailed;

  return (
    <button
      type="button"
      className="lx-gal-tile reveal"
      onClick={() => onOpen(item)}
      aria-label={alt}
    >
      {showPlaceholder ? (
        <AssetPlaceholder label={item.file} aspect="1/1" icon="图" />
      ) : (
        <span className="lx-gal-tile-media" style={{ aspectRatio: '1/1' }}>
          {probing ? <span className="lx-gal-tile-probe" aria-hidden="true" /> : null}
          <img
            src={src}
            alt={alt}
            loading="lazy"
            decoding="async"
            onError={() => setImgFailed(true)}
          />
        </span>
      )}
    </button>
  );
}

function GalleryLightbox({ item, lang, t, onClose }) {
  const src = item ? gallerySrc(item.file) : '';
  const exists = useAssetExists(item ? src : '');
  const [imgFailed, setImgFailed] = useState(false);
  const alt = item ? ((item.alt && item.alt[lang]) || item.alt.pl || item.file) : '';

  useEffect(() => {
    if (!item) return undefined;
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', onKey);
    document.body.style.overflow = 'hidden';
    return () => {
      window.removeEventListener('keydown', onKey);
      document.body.style.overflow = '';
    };
  }, [item, onClose]);

  useEffect(() => {
    setImgFailed(false);
  }, [item && item.file]);

  if (!item) return null;

  const showPlaceholder = exists === false || imgFailed;

  return (
    <div
      className="lx-gal-lightbox"
      role="dialog"
      aria-modal="true"
      aria-label={alt}
      onClick={onClose}
    >
      <div className="lx-gal-lightbox-inner" onClick={(e) => e.stopPropagation()}>
        <button
          type="button"
          className="lx-gal-lightbox-close"
          onClick={onClose}
          aria-label={t.gallery.lightboxClose}
        >
          ×
        </button>
        {showPlaceholder ? (
          <AssetPlaceholder label={item.file} aspect="1/1" icon="图" />
        ) : (
          <img
            src={src}
            alt={alt}
            className="lx-gal-lightbox-img"
            onError={() => setImgFailed(true)}
          />
        )}
        <p className="lx-gal-lightbox-cap">{alt}</p>
      </div>
    </div>
  );
}

function GallerySection({ lang, t }) {
  const manifest = window.GALLERY_MANIFEST || [];
  const categories = window.GALLERY_CATEGORIES || [];
  const [filter, setFilter] = useState('all');
  const [lightboxItem, setLightboxItem] = useState(null);

  const closeLightbox = useCallback(() => setLightboxItem(null), []);

  const filtered = useMemo(() => {
    if (filter === 'all') return manifest;
    return manifest.filter((item) => item.category === filter);
  }, [manifest, filter]);

  const catLabel = (id) => (t.gallery.categories && t.gallery.categories[id]) || id;

  return (
    <section className="lx-page-section">
      <div className="wrap">
        <div className="lx-gal">
          <div className="lx-shop-cats lx-gal-filters reveal">
            <button
              type="button"
              className={`lx-shop-cat-btn ${filter === 'all' ? 'on' : ''}`}
              onClick={() => setFilter('all')}
            >
              {t.gallery.filterAll}
            </button>
            {categories.map((id) => (
              <button
                key={id}
                type="button"
                className={`lx-shop-cat-btn ${filter === id ? 'on' : ''}`}
                onClick={() => setFilter(id)}
              >
                {catLabel(id)}
              </button>
            ))}
          </div>

          <div className="lx-gal-grid">
            {filtered.map((item) => (
              <GalleryThumb
                key={item.file}
                item={item}
                lang={lang}
                onOpen={setLightboxItem}
              />
            ))}
          </div>

          {filtered.length === 0 && (
            <p className="lx-gal-empty reveal">{t.gallery.empty}</p>
          )}
        </div>
      </div>

      <GalleryLightbox
        item={lightboxItem}
        lang={lang}
        t={t}
        onClose={closeLightbox}
      />
    </section>
  );
}

Object.assign(window, { GallerySection, GalleryThumb, GalleryLightbox });
