/* global React, Photo, Eyebrow, Rule, CTABand */

/* ------------------------------------------------------------------
   Gallery detail page — route: #gallery/<slug>
   Galleries listed in GALLERY_PHOTOS render real photographs; the rest
   fall back to brand-tinted gradient placeholders until their photos
   are ready.
   ------------------------------------------------------------------ */

const GALLERIES = {
  /* Portfolio categories */
  weddings:         { cat: 'The Weddings',          title: <>your best <em>celebration.</em></>,      meta: 'Athens & beyond' },
  engagements:      { cat: 'The Engagements',       title: <>starting your <em>forever.</em></>,      meta: 'Before the big day' },
  families:         { cat: 'The Families',          title: <>your people, <em>together.</em></>,      meta: 'The everyday, kept' },
  travel:           { cat: 'The Travel',            title: <>wherever it <em>leads.</em></>,          meta: 'Near & far' },
  reel:             { cat: 'The Reel',              title: <>a scrapbook of <em>last season.</em></>, meta: 'Recent moments, in passing' },
  /* Home "Selected Work" stories */
  'emma-dallas':    { cat: 'A Wedding Story',       title: <>Emma &amp; <em>Dallas.</em></>,          meta: 'A garden in Athens · June' },
  'first-look':     { cat: 'Lifestyle · Editorial', title: <>the first <em>look.</em></>,             meta: 'An editorial session' },
  'the-details':    { cat: 'The Details',           title: <>the small, <em>true things.</em></>,     meta: 'Athens, Georgia' },
  'caroline-wells': { cat: 'A Wedding Story',       title: <>Caroline &amp; <em>Wells.</em></>,       meta: 'A walk by the water · October' },
  'daphne-sam':     { cat: 'An Engagement',         title: <>Daphne &amp; <em>Sam.</em></>,           meta: 'The engagement · April' },
};

/* Real photo galleries. Filenames stored raw; encodeURI() at render handles
   spaces/parentheses. To add a gallery, drop a { base, files } entry here. */
const GALLERY_PHOTOS = {
  families: {
    base: 'assets/ahp-photos/Galleries/Families/',
    files: [
      'AHP-7.jpg', 'AHP-008.jpg', 'AHP-035.jpg', 'AHP-50.jpg', 'AHP-57.jpg',
      'AHP-068.jpg', 'AHP-073.jpg', 'AHP-076.jpg', 'AHP-76.jpg', 'AHP-85.jpg',
      'AHP-089.jpg', 'AHP-092.jpg', 'AHP-100.jpg', 'AHP-115.jpg', 'AHP-122.jpg',
      'AHP-123.jpg', 'AHP-124.jpg', 'AHP-128.jpg', 'AHP-138.jpg', 'AHP-146.jpg',
      'AHP-147.jpg', 'AHP-148.jpg', 'AHP-154.jpg', 'AHP-156.jpg', 'AHP-158.jpg',
      'AHP-163.jpg', 'AHP-167.jpg', 'AHP-176.jpg', 'AHP-190.jpg', 'AHP-202.jpg',
      'AHP-216 (1).jpg', 'AHP-241.jpg', 'AHP-255.jpg', 'AHP-316.jpg', 'AHP-325.jpg',
      'AHP-347.jpg', 'AHP-407.jpg', 'AHP-1265.jpg', 'AHP-1330.jpg', 'AHP-1333.jpg',
      'AHP-1341.jpg', 'AHP-1349.jpg', 'AP5A5682.jpg', 'AP5A5695.jpg', 'AP5A5713.jpg',
      'AP5A5889.jpg', 'AP5A6094.jpg',
    ],
  },
  engagements: {
    base: 'assets/ahp-photos/Galleries/Engagements/',
    files: [
      'AHP-003.jpg', 'AHP-004.jpg', 'AHP-008.jpg', 'AHP-10.jpg', 'AHP-017.jpg',
      'AHP-023.jpg', 'AHP-27.jpg', 'AHP-028.jpg', 'AHP-30.jpg', 'AHP-036.jpg',
      'AHP-040.jpg', 'AHP-48.jpg', 'AHP-54.jpg', 'AHP-55.jpg', 'AHP-057.jpg',
      'AHP-060.jpg', 'AHP-066.jpg', 'AHP-68.jpg', 'AHP-072.jpg', 'AHP-077.jpg',
      'AHP-88.jpg', 'AHP-089.jpg', 'AHP-089 (1).jpg', 'AHP-096.jpg', 'AHP-97.jpg',
      'AHP-101.jpg', 'AHP-102.jpg', 'AHP-107.jpg', 'AHP-109.jpg', 'AHP-115.jpg',
      'AHP-116 (1).jpg', 'AHP-121.jpg', 'AHP-126.jpg', 'AHP-126 (2).jpg', 'AHP-128.jpg',
      'AHP-134.jpg', 'AHP-135.jpg', 'AHP-141.jpg', 'AHP-142.jpg', 'AHP-151.jpg',
      'AHP-156.jpg', 'AHP-161.jpg', 'AHP-166.jpg', 'AHP-170.jpg', 'AHP-176.jpg',
      'AHP-198.jpg', 'AHP-207.jpg', 'AHP-218.jpg', 'AHP-218 (2).jpg', 'AHP-219.jpg',
      'AHP-225.jpg', 'AHP-228.jpg', 'AHP-231.jpg', 'AHP-242.jpg', 'AHP-243.jpg',
      'AHP-245.jpg', 'AHP-246.jpg', 'AHP-271.jpg', 'AHP-363.jpg', 'AHP-404.jpg',
      'AHP-420.jpg', 'AHP-432.jpg', 'AHP-440.jpg', 'AHP-453.jpg', 'AHP-471 (1).jpg',
      'AHP-482.jpg', 'AHP-514.jpg', 'AHP-539.jpg', 'AHP-552.jpg', 'AP5A4311.jpg',
      'AP5A4363.jpg', 'AP5A4368.jpg', 'AP5A4446.jpg', 'AP5A4496.jpg', 'AP5A4506.jpg',
      'AP5A4769.jpg', 'AP5A4937.jpg', 'AP5A4970.jpg', 'AP5A5111.jpg', 'AP5A5479.jpg',
    ],
  },
  travel: {
    base: 'assets/ahp-photos/Galleries/Travel/',
    files: [
      'DSCF2208.jpg', 'DSCF2234.jpg', 'DSCF2260.jpg', 'DSCF2267.jpg', 'DSCF2278.jpg',
      'DSCF2279.jpg', 'DSCF2316.jpg', 'DSCF2318.jpg', 'DSCF2329.jpg', 'DSCF2339.jpg',
      'DSCF2346.jpg', 'DSCF2349.jpg', 'DSCF2409.jpg', 'DSCF2412.jpg', 'DSCF2442.jpg',
      'DSCF2459.jpg', 'DSCF2480.jpg', 'DSCF2490.jpg', 'DSCF2522.jpg', 'DSCF2523.jpg',
      'DSCF2529.jpg', 'DSCF2533.jpg', 'DSCF2574.jpg', 'DSCF2601.jpg', 'DSCF2606.jpg',
      'DSCF2620.jpg', 'DSCF2635.jpg', 'DSCF2642.jpg', 'DSCF2654.jpg', 'DSCF2700.jpg',
      'DSCF2703.jpg', 'DSCF2734.jpg', 'DSCF2749.jpg', 'DSCF2760.jpg', 'DSCF2769.jpg',
      'DSCF2793.jpg', 'DSCF2795.jpg', 'DSCF2811.jpg', 'DSCF2846.jpg', 'DSCF2862.jpg',
      'DSCF2875.jpg', 'DSCF2889.jpg', 'DSCF2890.jpg', 'DSCF2903.jpg', 'DSCF2912.jpg',
      'DSC_9133.JPG', 'DSC_9169.JPG', 'DSC_9210.JPG', 'DSC_9216.JPG', 'GPTempDownload.jpg',
      'IMG_1189.jpeg', 'IMG_1233.jpeg', 'IMG_1237.jpeg', 'IMG_1648.jpeg', 'IMG_1665.jpeg',
      'IMG_2196.jpeg', 'IMG_2445.jpeg', 'IMG_4564.jpeg', 'IMG_4606.jpeg', 'IMG_5254.jpeg',
      'IMG_5269.jpeg', 'IMG_5305.jpeg', 'IMG_5310.jpeg', 'IMG_5323.jpeg', 'IMG_5458.jpeg',
      'IMG_5624.jpeg', 'IMG_5686.jpeg', 'IMG_5706.jpeg', 'IMG_5789.jpeg', 'IMG_5798.jpeg',
      'IMG_5804.jpeg', 'IMG_5873.jpeg', 'IMG_5894.jpeg', 'IMG_5899.jpeg', 'IMG_5900.jpeg',
      'IMG_6920.jpeg', 'IMG_6936.jpeg', 'IMG_7250.jpeg', 'IMG_7284.jpeg', 'IMG_7290.jpeg',
    ],
  },
  weddings: {
    base: 'assets/ahp-photos/Galleries/Weddings/',
    files: [
      '896A2601.jpg', '896A2926.jpg', '896A2996.jpg', 'AHP-58.jpg', 'AHP-066.jpg',
      'AHP-071.jpg', 'AHP-105.jpg', 'AHP-159.jpg', 'AHP-228.jpg', 'AHP-235.jpg',
      'AHP-238.jpg', 'AHP-243.jpg', 'AHP-249.jpg', 'AHP-250.jpg', 'AHP-265.jpg',
      'AHP-277.jpg', 'AHP-284.jpg', 'AHP-289.jpg', 'AHP-290.jpg', 'AHP-294.jpg',
      'AHP-295.jpg', 'AHP-297.jpg', 'AHP-298.jpg', 'AHP-298 (1).jpg', 'AHP-299.jpg',
      'AHP-300.jpg', 'AHP-301.jpg', 'AHP-311.jpg', 'AHP-314 (1).jpg', 'AHP-334.jpg',
      'AHP-342.jpg', 'AHP-348.jpg', 'AHP-350.jpg', 'AHP-351.jpg', 'AHP-353.jpg',
      'AHP-354.jpg', 'AHP-363.jpg', 'AHP-364.jpg', 'AHP-365.jpg', 'AHP-367.jpg',
      'AHP-370.jpg', 'AHP-371.jpg', 'AHP-372.jpg', 'AHP-389.jpg', 'AHP-393.jpg',
      'AHP-393 (1).jpg', 'AHP-394.jpg', 'AHP-399.jpg', 'AHP-403.jpg', 'AHP-408.jpg',
      'AHP-415 (1).jpg', 'AHP-417.jpg', 'AHP-420.jpg', 'AHP-424.jpg', 'AHP-425.jpg',
      'AHP-429.jpg', 'AHP-447.jpg', 'AHP-450.jpg', 'AHP-459.jpg', 'AHP-471 (1).jpg',
      'AHP-474.jpg', 'AHP-512.jpg', 'AHP-554.jpg', 'AHP-563.jpg', 'AHP-587.jpg',
      'AHP-589.jpg', 'AHP-591 (1).jpg', 'AHP-719.jpg', 'AHP-731.jpg', 'AHP-735.jpg',
      'AHP-764.jpg', 'AHP-825.jpg', 'AHP-878.jpg', 'AHP-912.jpg', 'AHP-927.jpg',
      'AHP-966.jpg', 'AHP-1084.jpg', 'AHP-1104.jpg', 'AHP-1118.jpg', 'AHP-1254.jpg',
      'AHP-1265.jpg', 'AHP-1313.jpg', 'AHP-1346.jpg', 'AHP-1350.jpg',
    ],
  },
};

/* Editorial 12-column layout — mixed widths so the rhythm feels curated. */
const GALLERY_FRAMES = [
  { tone: 'warm',   span: '1 / span 7',  h: 560 },
  { tone: 'rose',   span: '8 / span 5',  h: 560 },
  { tone: 'green',  span: '1 / span 4',  h: 420 },
  { tone: 'field',  span: '5 / span 4',  h: 420 },
  { tone: 'dusk',   span: '9 / span 4',  h: 420 },
  { tone: 'garden', span: '1 / span 5',  h: 480 },
  { tone: 'warm',   span: '6 / span 7',  h: 480 },
  { tone: 'rose',   span: '1 / span 12', h: 520 },
  { tone: 'field',  span: '1 / span 4',  h: 420 },
  { tone: 'warm',   span: '5 / span 4',  h: 420 },
  { tone: 'green',  span: '9 / span 4',  h: 420 },
  { tone: 'dusk',   span: '1 / span 5',  h: 480 },
  { tone: 'rose',   span: '6 / span 7',  h: 480 },
];

/* Responsive column count (3 desktop / 2 tablet / 1 mobile). Resizes are
   debounced with rAF — a drag across the window edge otherwise re-deals every
   photo into new columns on every single resize event. */
function useColumnCount() {
  const get = () => (typeof window === 'undefined' ? 3
    : window.innerWidth <= 560 ? 1
    : window.innerWidth <= 900 ? 2 : 3);
  const [cols, setCols] = React.useState(get);
  React.useEffect(() => {
    let frame = null;
    const onResize = () => {
      if (frame) return;
      frame = requestAnimationFrame(() => { frame = null; setCols(get()); });
    };
    window.addEventListener('resize', onResize);
    return () => {
      window.removeEventListener('resize', onResize);
      if (frame) cancelAnimationFrame(frame);
    };
  }, []);
  return cols;
}

/* Real-photo masonry. Images are dealt round-robin across columns so DOM
   order runs left-to-right, top-to-bottom — which means the browser loads the
   top rows first and defers everything below the fold (native lazy loading),
   so you never watch the last photos pop in. The first two rows load eagerly
   so the top of the gallery is there immediately. */
function PhotoGallery({ base, files }) {
  const cols = useColumnCount();
  const columns = Array.from({ length: cols }, () => []);
  files.forEach((name, i) => columns[i % cols].push({ name, i }));

  return (
    <div className="gallery-cols">
      {columns.map((col, ci) => (
        <div className="gallery-col" key={ci}>
          {col.map(({ name, i }) => (
            <img
              key={name}
              src={asset(encodeURI(base + name))}
              alt=""
              className="gallery-cols__img"
              loading={i < cols * 2 ? 'eager' : 'lazy'}
              onError={(e) => { e.currentTarget.style.display = 'none'; }}
            />
          ))}
        </div>
      ))}
    </div>
  );
}

/* Placeholder editorial frames — for galleries whose photos aren't ready. */
function PlaceholderFrames() {
  return (
    <div className="frames">
      {GALLERY_FRAMES.map((f, i) => (
        <div key={i} className="frames__item" style={{ '--span': f.span, '--h': `${f.h}px` }}>
          <Photo tone={f.tone} aspect={null} caption={`Frame N° ${String(i + 1).padStart(2, '0')}`} />
        </div>
      ))}
    </div>
  );
}

function GalleryPage({ onNav, param }) {
  const g = GALLERIES[param] || { cat: 'The Galleries', title: <>a quiet <em>gallery.</em></>, meta: 'Coming soon' };
  const photos = GALLERY_PHOTOS[param];

  return (
    <React.Fragment>
      <header className="page-header" style={{ paddingBottom: 40 }}>
        <div className="page-header__inner">
          <Eyebrow center>{g.cat}</Eyebrow>
          <h1 className="kit-headline kit-headline--xl" style={{ margin: '32px 0 24px' }}>{g.title}</h1>
          <Rule center />
          <p style={{
            fontFamily: 'var(--font-sans)', fontSize: 11, letterSpacing: '0.28em',
            textTransform: 'uppercase', color: 'var(--fg-muted)', margin: 0
          }}>
            {photos ? `${g.meta} · ${photos.files.length} photographs` : g.meta}
          </p>
        </div>
      </header>

      <section className="gallery-section">
        <div className="gallery-section__inner">
          <div className="gallery-section__bar">
            <button className="kit-btn kit-btn--ghost" onClick={() => onNav('portfolio')}>
              All the Galleries
            </button>
            {!photos && <span className="ah-caption">Placeholder frames · photographs coming soon</span>}
          </div>
          {photos ? <PhotoGallery base={photos.base} files={photos.files} /> : <PlaceholderFrames />}
        </div>
      </section>

      <CTABand
        onNav={onNav}
        title={<>Picture your own <em>day here?</em></>}
        body="Tell me a little about what you're dreaming up — I'll send the full guide with collection details, real timelines, and a few words on how I work."
      />
    </React.Fragment>
  );
}

/* PhotoGallery is shared with the journal, which renders each post as a
   gallery of its own. */
Object.assign(window, { GalleryPage, PhotoGallery });
