// Gallery + fullscreen viewer.

const GalleryPage = ({ onOpenPhoto }) => {
  const [set, setSet] = React.useState('all');
  const style = window.TWEAKS.galleryStyle;
  const filtered = set === 'all' ? PHOTOS : PHOTOS.filter(p => p.set === set);

  return (
    <div className="page__inner fade-in">
      <div className="eyebrow" style={{ marginBottom: 12 }}>Section</div>
      <h1 className="display" style={{ fontSize: 'clamp(34px, 5vw, 62px)', marginBottom: 8 }}>Photographs</h1>
      <p className="serif" style={{ fontSize: 18, color: 'var(--bone-soft)', marginBottom: 36, maxWidth: 720 }}>
        Browse a set, or view everything at once. Tap any frame for fullscreen.
      </p>

      {/* Set switcher */}
      <div style={{ display: 'flex', gap: 8, marginBottom: 36, flexWrap: 'wrap' }}>
        <SetPill active={set === 'all'} onClick={() => setSet('all')} label="All Photos" count={PHOTOS.length} />
        {GALLERY_SETS.map(s => (
          <SetPill key={s.id} active={set === s.id} onClick={() => setSet(s.id)} label={s.title} count={PHOTOS.filter(p=>p.set===s.id).length}/>
        ))}
      </div>

      {style === 'mosaic' && <MosaicLayout photos={filtered} onOpen={onOpenPhoto} />}
      {style === 'grid' && <GridLayout photos={filtered} onOpen={onOpenPhoto} />}
      {style === 'filmstrip' && <FilmstripLayout photos={filtered} onOpen={onOpenPhoto} />}
    </div>
  );
};

const SetPill = ({ active, onClick, label, count }) => (
  <div onClick={onClick} style={{
    padding: '10px 18px',
    borderRadius: 999,
    background: active ? 'var(--bone)' : 'var(--glass-bg)',
    backdropFilter: 'blur(var(--glass-blur))',
    border: '1px solid ' + (active ? 'var(--bone)' : 'var(--glass-border)'),
    color: active ? 'var(--ink)' : 'var(--bone-soft)',
    fontFamily: 'var(--font-ui)',
    fontSize: 10, letterSpacing: '0.22em', textTransform: 'uppercase',
    cursor: 'pointer',
    display: 'inline-flex', alignItems: 'center', gap: 10,
    transition: 'all 200ms',
  }}>
    <span>{label}</span>
    <span style={{ opacity: 0.6, fontSize: 9 }}>{count}</span>
  </div>
);

// Asymmetric mosaic
const MosaicLayout = ({ photos, onOpen }) => {
  // create a deterministic pattern: some tall, some wide
  const patterns = ['span 2 / span 1', 'span 1 / span 1', 'span 1 / span 2', 'span 1 / span 1', 'span 2 / span 2', 'span 1 / span 1', 'span 1 / span 1', 'span 1 / span 1'];
  return (
    <div className="reveal-stagger drift" style={{
      display: 'grid',
      gridTemplateColumns: 'repeat(4, 1fr)',
      gridAutoRows: '200px',
      gap: 12,
    }}>
      {photos.map((p, i) => (
        <div key={p.id} style={{ gridRow: patterns[i % patterns.length].split(' / ')[0], gridColumn: patterns[i % patterns.length].split(' / ')[1] }}>
          <PhotoTile photo={p} onClick={() => onOpen(i, photos)} style={{ width: '100%', height: '100%' }}/>
        </div>
      ))}
    </div>
  );
};

const GridLayout = ({ photos, onOpen }) => (
  <div className="reveal-stagger drift" style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(240px, 1fr))', gap: 12 }}>
    {photos.map((p, i) => (
      <PhotoTile key={p.id} photo={p} onClick={() => onOpen(i, photos)} style={{ aspectRatio: '1 / 1', borderRadius: 10 }}/>
    ))}
  </div>
);

const FilmstripLayout = ({ photos, onOpen }) => (
  <div className="reveal-stagger drift" style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
    {chunk(photos, 3).map((row, r) => (
      <div key={r} style={{ display: 'grid', gridTemplateColumns: r % 2 === 0 ? '2fr 1fr 1fr' : '1fr 1fr 2fr', gap: 10, height: 280 }}>
        {row.map((p, i) => (
          <PhotoTile key={p.id} photo={p} onClick={() => onOpen(photos.indexOf(p), photos)} style={{ width: '100%', height: '100%', borderRadius: 10 }}/>
        ))}
      </div>
    ))}
  </div>
);

const chunk = (arr, n) => {
  const out = [];
  for (let i = 0; i < arr.length; i += n) out.push(arr.slice(i, i + n));
  return out;
};

// ────────── Fullscreen Viewer ──────────
const FullscreenViewer = ({ photos, index, onClose, onIndex }) => {
  const [showUI, setShowUI] = React.useState(true);
  const [showMeta, setShowMeta] = React.useState(true);

  React.useEffect(() => {
    const onKey = (e) => {
      if (e.key === 'Escape') onClose();
      if (e.key === 'ArrowRight') onIndex((index + 1) % photos.length);
      if (e.key === 'ArrowLeft') onIndex((index - 1 + photos.length) % photos.length);
      if (e.key.toLowerCase() === 'h') setShowUI(s => !s);
      if (e.key.toLowerCase() === 'i') setShowMeta(s => !s);
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [index, photos.length, onClose, onIndex]);

  const p = photos[index];
  const fullUrl = p.full || p.bg || null;
  const thumbUrl = p.thumb || p.bg || null;

  // Preload neighbor full-res images so ←/→ navigation is instant.
  // Preload at 1600px (bg) rather than 3200px (full) — fast on phones,
  // still sharp on desktop; the 3200px only streams in once viewed.
  React.useEffect(() => {
    const preload = (i) => {
      const q = photos[(i + photos.length) % photos.length];
      const url = q && (q.bg || q.full || null);
      if (url) { const img = new Image(); img.src = url; }
    };
    preload(index + 1);
    preload(index - 1);
  }, [index, photos]);

  return (
    <div style={{
      position: 'fixed', inset: 0, zIndex: 200,
      background: '#000',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
    }}>
      {/* Photo layer — low-res thumb behind, full-res on top as it loads */}
      <div
        onClick={() => setShowMeta(m => !m)}
        style={{
          position: 'absolute', inset: 0,
          cursor: 'pointer',
          background: '#000',
        }}
      >
        {thumbUrl && (
          <img
            key={'thumb-' + p.id}
            src={thumbUrl}
            alt=""
            aria-hidden="true"
            decoding="async"
            style={{
              position: 'absolute', inset: 0, width: '100%', height: '100%',
              objectFit: 'contain', objectPosition: 'center',
              filter: 'blur(8px)',
              transform: 'scale(1.02)',
            }}
          />
        )}
        {fullUrl && (
          <img
            key={'full-' + p.id}
            src={fullUrl}
            srcSet={p.srcset}
            sizes="100vw"
            alt={p.title || ''}
            decoding="async"
            style={{
              position: 'absolute', inset: 0, width: '100%', height: '100%',
              objectFit: 'contain', objectPosition: 'center',
            }}
          />
        )}
      </div>
      {/* Darken edges when UI shown */}
      {showUI && (
        <div style={{
          position: 'absolute', inset: 0, pointerEvents: 'none',
          background: 'radial-gradient(ellipse at center, transparent 50%, rgba(0,0,0,0.6) 100%)',
        }}/>
      )}

      {/* Close button */}
      {showUI && (
        <div style={{ position: 'absolute', top: 24, right: 24, zIndex: 3 }}>
          <div className="glass glass-interactive" onClick={onClose} style={{
            width: 48, height: 48, borderRadius: '50%',
            display: 'grid', placeItems: 'center', color: 'var(--bone)', cursor: 'pointer',
          }}>
            <Icon name="close" size={18}/>
          </div>
        </div>
      )}

      {/* Counter top center */}
      {showUI && (
        <div className="glass glass--pill" style={{
          position: 'absolute', top: 28, left: '50%', transform: 'translateX(-50%)',
          padding: '8px 18px',
          fontFamily: 'var(--font-ui)',
          fontSize: 10, letterSpacing: '0.28em', textTransform: 'uppercase',
          color: 'var(--bone-soft)',
          zIndex: 3,
        }}>
          {String(index + 1).padStart(2,'0')} / {String(photos.length).padStart(2,'0')}
        </div>
      )}

      {/* Arrows */}
      {showUI && (
        <>
          <div className="glass glass-interactive" onClick={(e) => { e.stopPropagation(); onIndex((index - 1 + photos.length) % photos.length); }} style={{
            position: 'absolute', left: 30, top: '50%', transform: 'translateY(-50%)',
            width: 56, height: 56, borderRadius: '50%',
            display: 'grid', placeItems: 'center', color: 'var(--bone)', zIndex: 3,
          }}>
            <Icon name="arrow-left" size={20}/>
          </div>
          <div className="glass glass-interactive" onClick={(e) => { e.stopPropagation(); onIndex((index + 1) % photos.length); }} style={{
            position: 'absolute', right: 30, top: '50%', transform: 'translateY(-50%)',
            width: 56, height: 56, borderRadius: '50%',
            display: 'grid', placeItems: 'center', color: 'var(--bone)', zIndex: 3,
          }}>
            <Icon name="arrow-right" size={20}/>
          </div>
        </>
      )}

      {/* Metadata glass block — bottom left */}
      {showUI && showMeta && (
        <GlassBox style={{
          position: 'absolute', left: 30, bottom: 30, zIndex: 3,
          padding: '22px 26px', maxWidth: 460,
        }}>
          <div className="eyebrow" style={{ marginBottom: 8 }}>Photograph · {p.date}</div>
          <h3 className="display" style={{ fontSize: 22, fontWeight: 500, marginBottom: 10 }}>{p.title}</h3>
          <div style={{ display: 'flex', gap: 10, alignItems: 'center', color: 'var(--bone-soft)', fontFamily: 'var(--font-serif)', fontSize: 15, marginBottom: 12 }}>
            <Icon name="location" size={14}/>
            <span>{p.loc}</span>
          </div>
          <div style={{ display: 'flex', gap: 10, alignItems: 'flex-start', color: 'var(--bone-dim)', fontFamily: 'var(--font-ui)', fontSize: 11, letterSpacing: '0.06em' }}>
            <Icon name="camera" size={14}/>
            <span style={{ lineHeight: 1.5 }}>{p.camera}</span>
          </div>
        </GlassBox>
      )}

      {/* Hint — bottom right */}
      {showUI && (
        <div style={{
          position: 'absolute', right: 30, bottom: 30, zIndex: 3,
          fontFamily: 'var(--font-ui)', fontSize: 9, letterSpacing: '0.24em', textTransform: 'uppercase',
          color: 'var(--bone-dim)', textAlign: 'right', lineHeight: 1.8,
        }}>
          <div>Tap photo · Toggle info</div>
          <div>H · Hide all UI</div>
          <div>← → · Navigate</div>
        </div>
      )}

      {/* Hide-UI floating hint */}
      {!showUI && (
        <div onClick={() => setShowUI(true)} style={{
          position: 'absolute', bottom: 20, left: '50%', transform: 'translateX(-50%)',
          fontFamily: 'var(--font-ui)', fontSize: 9, letterSpacing: '0.28em', textTransform: 'uppercase',
          color: 'rgba(255,255,255,0.25)', cursor: 'pointer', zIndex: 3,
        }}>
          Press H to show UI
        </div>
      )}
    </div>
  );
};

Object.assign(window, { GalleryPage, FullscreenViewer });
