/* global React, Photo, Eyebrow, Rule, CTABand */
const { useState: useStateJ } = React;

/* ------------------------------------------------------------------
   The Journal — each entry is a preview gallery with a few notes on
   the day, not a long-form essay.

   ADDING AN ENTRY
   1. Drop the photographs in assets/ahp-photos-original/Journal/<slug>/,
      keeping whatever names they came off the card with.
   2. Run scripts/downsample-photos.sh (mirrors them to assets/ahp-photos/).
   3. Add an entry to POSTS below, newest first, listing the filenames in the
      order they should appear. scripts/list-journal-photos.sh <slug> prints
      that list ready to paste.

   See ASSETS.md for the full walk-through.
   ------------------------------------------------------------------ */

const CATEGORIES = ['Wedding', 'Engagement', 'Family', 'Travel'];

const POSTS = [
  {
    n: '05',
    slug: 'ki-and-madeline',
    cat: 'Engagement',
    title: 'Ki & Madeline',
    date: 'June 7, 2026',
    place: 'Athens, Georgia',
    tone: 'dusk',
    photos: {
        base: 'assets/ahp-photos/Journal/ki-and-madeline/',
        files: [
          'AHP-4.jpg', 'AHP-6.jpg', 'AHP-9.jpg', 'AHP-10.jpg', 'AHP-11.jpg',
          'AHP-14.jpg', 'AHP-15.jpg', 'AHP-17.jpg', 'AHP-21.jpg', 'AHP-27.jpg',
          'AHP-30.jpg', 'AHP-33.jpg', 'AHP-41.jpg', 'AHP-42.jpg', 'AHP-45.jpg',
          'AHP-49.jpg', 'AHP-54.jpg', 'AHP-57.jpg', 'AHP-65.jpg', 'AHP-66.jpg',
          'AHP-68.jpg', 'AHP-73.jpg', 'AHP-77.jpg', 'AHP-81.jpg', 'AHP-83.jpg',
          'AHP-88.jpg', 'AHP-90.jpg', 'AHP-92.jpg', 'AHP-94.jpg', 'AHP-104.jpg',
          'AHP-107.jpg', 'AHP-108.jpg', 'AHP-110.jpg', 'AHP-112.jpg', 'AHP-114.jpg',
          'AHP-115.jpg', 'AHP-118.jpg', 'AHP-123.jpg', 'AHP-126.jpg', 'AHP-130.jpg',
          'AHP-132.jpg', 'AHP-134 (1).jpg', 'AHP-135.jpg', 'AHP-142.jpg', 'AHP-145.jpg',
          'AHP-152.jpg', 'AHP-154.jpg', 'AHP-163.jpg', 'AHP-173.jpg', 'AHP-177.jpg',
          'AHP-182.jpg', 'AHP-189.jpg', 'AHP-191.jpg', 'AHP-194.jpg', 'AHP-198.jpg',
          'AHP-202.jpg', 'AHP-205.jpg', 'AHP-206.jpg', 'AHP-211.jpg', 'AHP-219.jpg',
          'AHP-226.jpg', 'AHP-229.jpg', 'AHP-234.jpg', 'AHP-237.jpg', 'AHP-242.jpg',
          'AHP-245.jpg', 'AHP-247.jpg',
        ],
    },
    body: [
      "Reconnecting with Madeline during this engagement season has been so fun. I so enjoyed meeting her fiance, Ki, and exploring Athens. They knew they wanted a classic, sophisticated look to their photos, but the creek behind Madeline’s apartment holds many memories with their dog, Dooley. When I told Madeline that both locations were an option, the plan fell perfectly into place! We had the best time laughing our way through the evening. Cheers to Ki & Madeline!",
    ],
  },
  {
    n: '02',
    slug: 'classic-city-wedding',
    cat: 'Wedding',
    title: 'A Classic City Wedding',
    date: 'May 23, 2026',
    place: 'Athens, Georgia',
    tone: 'rose',
    photos: {
        base: 'assets/ahp-photos/Journal/dallas-and-emma-kate/',
        files: [
          'AHP-02.jpg', 'AHP-10.jpg', 'AHP-13.jpg', 'AHP-18.jpg', 'AHP-29.jpg',
          'AHP-37.jpg', 'AHP-42.jpg', 'AHP-49.jpg', 'AHP-54.jpg', 'AHP-58.jpg',
          'AHP-064.jpg', 'AHP-071.jpg', 'AHP-087.jpg', 'AHP-090.jpg', 'AHP-091.jpg',
          'AHP-096.jpg', 'AHP-103.jpg', 'AHP-107.jpg', 'AHP-112.jpg', 'AHP-114.jpg',
          'AHP-115.jpg', 'AHP-359.jpg', 'AHP-363.jpg', 'AHP-376.jpg', 'AHP-383.jpg',
          'AHP-396.jpg', 'AHP-398.jpg', 'AHP-400.jpg', 'AHP-403.jpg', 'AHP-416.jpg',
          'AHP-423.jpg', 'AHP-436.jpg', 'AHP-440.jpg', 'AHP-523 (1).jpg', 'AHP-534.jpg',
          'AHP-535.jpg', 'AHP-549.jpg', 'AHP-556.jpg', 'AHP-573.jpg', 'AHP-579.jpg',
          'AHP-587.jpg', 'AHP-599.jpg', 'AHP-610.jpg', 'AHP-616.jpg', 'AHP-618.jpg',
          'AHP-676.jpg', 'AHP-701.jpg', 'AHP-706.jpg', 'AHP-724.jpg', 'AHP-742.jpg',
          'AHP-752.jpg', 'AHP-753.jpg', 'AHP-789.jpg', 'AHP-791.jpg', 'AHP-799.jpg',
          'AHP-804.jpg', 'AHP-805.jpg', 'AHP-806.jpg', 'AHP-815.jpg', 'AHP-834.jpg',
          'AHP-851.jpg', 'AHP-854.jpg', 'AHP-865.jpg', 'AHP-866.jpg', 'AHP-897.jpg',
          'AHP-899.jpg', 'AHP-903.jpg', 'AHP-922.jpg', 'AHP-925.jpg', 'AHP-936.jpg',
          'AHP-975.jpg', 'AHP-988.jpg', 'AHP-1058.jpg', 'AHP-1063.jpg', 'AHP-1082.jpg',
          'AHP-1088.jpg', 'AHP-1094.jpg', 'AHP-1168.jpg', 'AHP-1177.jpg', 'AHP-1206.jpg',
          'AHP-1208.jpg', 'AHP-1229.jpg', 'AHP-1241.jpg', 'AHP-1251.jpg', 'AHP-1255.jpg',
          'AHP-1264.jpg', 'AHP-1276.jpg', 'AHP-1279.jpg', 'AHP-1281.jpg', 'AHP-1310.jpg',
          'AHP-1315.jpg', 'AHP-1321.jpg', 'AHP-1326.jpg', 'AHP-1328.jpg', 'AHP-1336.jpg',
          'AHP-1338.jpg', 'AHP-1346.jpg', 'AHP-1350.jpg', 'AHP-1353.jpg', 'AHP-1354.jpg',
          'AHP-1356.jpg', 'AHP-1362.jpg', 'AHP-1366.jpg', 'AHP-1374.jpg', 'AHP-1385.jpg',
          'AHP-1392.jpg', 'AHP-1394.jpg',
        ],
    },
    body: [
      "Introducing Mr. & Mrs. Pettus! From the trolley, the gorgeous downtown church, and the historic home reception, this wedding was truly a Classic City showstopper! Dallas and Emma Kate married one another surrounded by their closest friends and threw the most amazing party to celebrate — the dance floor was on fire!",
    ],
  },
  {
    n: '01',
    slug: 'jack-and-katie',
    cat: 'Engagement',
    title: 'Jack & Katie',
    date: 'April 1, 2026',
    place: 'Savannah, Georgia',
    tone: 'warm',
    photos: {
      base: 'assets/ahp-photos/Journal/jack-and-katie/',
      // Shoot order. One name carries a space and parentheses; the masonry runs
      // them through encodeURI, so they are stored raw here.
      files: [
        'AHP-10.jpg', 'AHP-19.jpg', 'AHP-24.jpg', 'AHP-27.jpg', 'AHP-31.jpg',
        'AHP-36.jpg', 'AHP-39.jpg', 'AHP-41.jpg', 'AHP-48.jpg', 'AHP-53.jpg',
        'AHP-56 (1).jpg', 'AHP-61.jpg', 'AHP-63.jpg', 'AHP-74.jpg', 'AHP-83.jpg',
        'AHP-88.jpg', 'AHP-97.jpg', 'AHP-102.jpg', 'AHP-109.jpg', 'AHP-112.jpg',
        'AHP-115.jpg', 'AHP-124.jpg', 'AHP-125.jpg', 'AHP-138.jpg', 'AHP-158.jpg',
        'AHP-166.jpg', 'AHP-170.jpg', 'AHP-174.jpg', 'AHP-200.jpg', 'AHP-206.jpg',
        'AHP-216.jpg', 'AHP-222.jpg', 'AHP-229.jpg', 'AHP-233.jpg', 'AHP-239.jpg',
      ],
    },
    body: [
      "Spending the morning with Katie and Jack was nothing short of magical. We spent the morning at the Wormsloe Historic Site, The Isle of Hope Marina, and White Bluff Drive. The Spanish Moss was the perfect backdrop.",
      "Couples like Katie and Jack make me LOVE my job — they were kind, intentional, and head over heels for each other. November here we come — Katie and Jack are getting married!",
    ],
  },
  {
    n: '04',
    slug: 'the-mansour-family',
    cat: 'Family',
    title: 'The Mansour Family',
    date: 'February 16, 2026',
    tone: 'garden',
    photos: {
        base: 'assets/ahp-photos/Journal/mansour-family/',
        files: [
          'AHP-172.jpg', 'AHP-175.jpg', 'AHP-178.jpg', 'AHP-180.jpg', 'AHP-181.jpg',
          'AHP-181 (1).jpg', 'AHP-185.jpg', 'AHP-189.jpg', 'AHP-192.jpg', 'AHP-193.jpg',
          'AHP-210.jpg', 'AHP-213.jpg', 'AHP-216.jpg', 'AHP-217.jpg', 'AHP-222.jpg',
          'AHP-230.jpg', 'AHP-234.jpg', 'AHP-239.jpg', 'AHP-242.jpg', 'AHP-243.jpg',
          'AHP-250.jpg', 'AHP-254.jpg', 'AHP-258.jpg', 'AHP-262.jpg', 'AHP-266.jpg',
          'AHP-276.jpg', 'AHP-282.jpg', 'AHP-295.jpg', 'AHP-297.jpg', 'AHP-302.jpg',
          'AHP-305.jpg', 'AHP-317.jpg', 'AHP-319.jpg', 'AHP-321.jpg', 'AHP-327.jpg',
          'AHP-331.jpg', 'AHP-339.jpg', 'AHP-341.jpg', 'AHP-348.jpg', 'AHP-353.jpg',
          'AHP-357.jpg', 'AHP-361.jpg', 'AHP-365.jpg', 'AHP-369.jpg', 'AHP-372.jpg',
          'AHP-376.jpg', 'AHP-378.jpg', 'AHP-382.jpg', 'AHP-387.jpg', 'AHP-389.jpg',
          'AHP-396.jpg', 'AHP-400.jpg', 'AHP-403.jpg', 'AHP-413.jpg', 'AHP-420.jpg',
          'AHP-429.jpg', 'AHP-440.jpg',
        ],
    },
    body: [
      "Hal and Peyton welcomed their sweet son, Harry, into the world this year. From being a part of their engagement and wedding, watching their family grow has been such a joy. Harry is so loved!",
    ],
  },
  {
    n: '03',
    slug: 'sydney-and-grant',
    cat: 'Engagement',
    title: 'Sydney and Grant',
    date: 'February 5, 2026',
    place: 'Athens, Georgia',
    tone: 'field',
    photos: {
        base: 'assets/ahp-photos/Journal/grant-and-sydney/',
        files: [
          'AHP-003.jpg', 'AHP-008.jpg', 'AHP-015.jpg', 'AHP-018.jpg', 'AHP-024.jpg',
          'AHP-029.jpg', 'AHP-033.jpg', 'AHP-044.jpg', 'AHP-053.jpg', 'AHP-060.jpg',
          'AHP-068.jpg', 'AHP-072.jpg', 'AHP-076.jpg', 'AHP-081.jpg', 'AHP-082.jpg',
          'AHP-085.jpg', 'AHP-089.jpg', 'AHP-094.jpg', 'AHP-098 (1).jpg', 'AHP-101.jpg',
          'AHP-106.jpg', 'AHP-108.jpg', 'AHP-112.jpg', 'AHP-116 (1).jpg', 'AHP-119.jpg',
          'AHP-127.jpg', 'AHP-134.jpg', 'AHP-138.jpg', 'AHP-143.jpg', 'AHP-146.jpg',
          'AHP-157.jpg', 'AHP-161.jpg', 'AHP-166.jpg', 'AHP-170.jpg', 'AHP-176.jpg',
          'AHP-180.jpg', 'AHP-186.jpg', 'AHP-187.jpg', 'AHP-189.jpg', 'AHP-193.jpg',
          'AHP-196.jpg', 'AHP-206.jpg', 'AHP-209.jpg', 'AHP-213.jpg', 'AHP-216.jpg',
          'AHP-218.jpg', 'AHP-222.jpg', 'AHP-224.jpg', 'AHP-227.jpg', 'AHP-228.jpg',
          'AHP-233.jpg', 'AHP-238.jpg', 'AHP-241.jpg', 'AHP-243.jpg', 'AHP-247.jpg',
          'AHP-251.jpg', 'AHP-254.jpg', 'AHP-256.jpg', 'AHP-273.jpg', 'AHP-275.jpg',
        ],
    },
    body: [
      "Taken at a private home tucked away in Athens, I had the best time getting to reconnect with Grant, a childhood friend, and his wonderful bride, Sydney. Her laugh was contagious and the three of us spent the entire time smiling! Their big day is in October at Hadden Estate and I cannot wait.",
      "Cheers to the Future Grahls!",
    ],
  },
  {
    n: '06',
    slug: 'the-wilsons',
    cat: 'Wedding',
    title: 'The Wilsons',
    date: 'October 11, 2025',
    place: 'Watkinsville, Georgia',
    tone: 'green',
    photos: {
        base: 'assets/ahp-photos/Journal/the-wilsons/',
        files: [
          'AHP-543.jpg', 'AHP-554.jpg', 'AHP-565.jpg', 'AHP-582.jpg', 'AHP-587.jpg',
          'AHP-591 (1).jpg', 'AHP-646 (1).jpg', 'AHP-676.jpg', 'AHP-678.jpg', 'AHP-690.jpg',
          'AHP-701.jpg', 'AHP-707.jpg', 'AHP-719.jpg', 'AHP-728.jpg', 'AHP-735.jpg',
          'AHP-750.jpg', 'AHP-765.jpg', 'AHP-769.jpg', 'AHP-792.jpg', 'AHP-796.jpg',
          'AHP-818.jpg', 'AHP-822.jpg', 'AHP-829.jpg', 'AHP-833.jpg', 'AHP-842.jpg',
          'AHP-852.jpg', 'AHP-876.jpg', 'AHP-878.jpg', 'AHP-889.jpg', 'AHP-908.jpg',
          'AHP-0971.jpg', 'AHP-1000.jpg', 'AHP-1023.jpg', 'AHP-1037.jpg', 'AHP-1040.jpg',
          'AHP-1052.jpg', 'AHP-1084.jpg', 'AHP-1101.jpg', 'AHP-1114.jpg', 'AHP-1120.jpg',
          'AHP-1137.jpg', 'AHP-1146.jpg', 'AHP-1180.jpg', 'AHP-1192.jpg', 'AHP-1198.jpg',
          'AHP-1202.jpg',
        ],
    },
    body: [
      "On a perfect day in October, Wright and Claire tied the knot at Hadden Estate in Watkinsville. Their day was surrounded by friends and family, beautiful weather, and gorgeous florals. It was an honor to capture their day — I’m thankful to call them both friends!",
    ],
  },
];

/* Photographs for an entry, in the order they appear on the page. Either
     files: ['AHP-10.jpg', …]   — keep the camera names, listed in shoot order
     count: 34                  — files are named 01.jpg … 34.jpg
   The first form is the default: it leaves Abby's archive filenames alone, and
   matches how GALLERY_PHOTOS works in GalleryPage.jsx. */
function postFiles(post) {
  if (!post || !post.photos) return [];
  const { files, count, ext = 'jpg' } = post.photos;
  if (files && files.length) return files;
  if (!count) return [];
  return Array.from({ length: count },
    (_, i) => `${String(i + 1).padStart(2, '0')}.${ext}`);
}

function postCover(post) {
  if (!post || !post.photos) return null;
  const files = postFiles(post);
  if (!files.length) return null;
  return post.photos.base + (post.photos.cover || files[0]);
}

function postHref(post) { return `post/${post.slug || post.n}`; }

function JournalHeader() {
  return (
    <header className="page-header page-header--wide">
      <div className="page-header__inner">
        <Eyebrow center>The Journal</Eyebrow>
        <h1 className="kit-headline kit-headline--lg headline-oneline" style={{ margin: '32px 0 24px' }}>
          letters, <em>lessons,</em> &amp; love-notes.
        </h1>
        <Rule center />
        <p className="kit-lede page-lede page-lede--center">
          A look back at recent sessions and wedding days — a few words on
          how each one went, and plenty of photographs.
        </p>
      </div>
    </header>
  );
}

function JournalFeatured({ post, onNav }) {
  const go = () => onNav(postHref(post));
  return (
    <section className="journal-feature">
      <div className="journal-feature__inner">
        <div style={{ cursor: 'pointer' }} onClick={go}>
          <Photo tone={post.tone} aspect="5/4" src={postCover(post)} />
        </div>
        <div>
          <div className="journal-feature__meta">
            {post.cat}{post.place ? ` · ${post.place}` : ''}
          </div>
          <h2 className="journal-feature__title">{post.title}</h2>
          <p className="journal-feature__dek">{post.dek || (post.body && post.body[0])}</p>
          <a className="kit-btn" href={`#${postHref(post)}`} onClick={(e) => { e.preventDefault(); go(); }}>
            See the Gallery
          </a>
        </div>
      </div>
    </section>
  );
}

function JournalCard({ post, onNav }) {
  return (
    <article className="journal-card" onClick={() => onNav(postHref(post))}>
      <Photo tone={post.tone} aspect="4/5" src={postCover(post)} />
      <div className="journal-card__meta">{post.cat}</div>
      <h3 className="journal-card__title">{post.title}</h3>
      <div className="journal-card__foot"><span>{post.date}</span></div>
    </article>
  );
}

function JournalList({ posts, onNav }) {
  const [active, setActive] = useStateJ('All');
  // Only offer a filter that would actually return something.
  const used = CATEGORIES.filter(c => posts.some(p => p.cat === c));
  const filters = used.length > 1 ? ['All'].concat(used) : [];
  const visible = active === 'All' ? posts : posts.filter(p => p.cat === active);

  return (
    <section className="journal-list">
      <div className="journal-list__head">
        <Eyebrow>The Archive</Eyebrow>
        <span className="journal-list__count">
          {visible.length} {visible.length === 1 ? 'Entry' : 'Entries'}
        </span>
      </div>
      {filters.length > 0 && (
        <div className="journal-list__filters">
          {filters.map(f => (
            <button
              key={f}
              className={`journal-list__filter ${active === f ? 'is-active' : ''}`}
              onClick={() => setActive(f)}
            >
              {f}
            </button>
          ))}
        </div>
      )}
      <div className="journal-list__grid">
        {visible.map(p => <JournalCard key={p.n} post={p} onNav={onNav} />)}
      </div>
    </section>
  );
}

function JournalPage({ onNav }) {
  // Newest entry leads; everything after it falls into the archive grid. With a
  // single entry the archive and its filters stay out of the way entirely.
  const featured = POSTS[0];
  const rest = POSTS.slice(1);
  return (
    <React.Fragment>
      <JournalHeader />
      {featured && <JournalFeatured post={featured} onNav={onNav} />}
      {rest.length > 0 && <JournalList posts={rest} onNav={onNav} />}
      <CTABand
        onNav={onNav}
        title={<>See something <em>you like?</em></>}
        body="If something here looks like the kind of morning you're picturing, send me a note. I'd love to hear what you're planning."
        primaryLabel="Inquire Now"
        primaryTarget="contact"
      />
    </React.Fragment>
  );
}

Object.assign(window, {
  JournalPage,
  JOURNAL_POSTS: POSTS,   // read by JournalPostPage.jsx
  postFiles, postCover, postHref,
});
