/* eslint-disable no-undef */
// My Work — gallery landing + category pages (hash-routed: #work, #work/<slug>)

/* ─── DATA ────────────────────────────────────────────────────── */
const WORK_CATEGORIES = [
  {
    slug: 'weddings',
    title: 'Weddings',
    lede: 'Full wedding days — from ceremony to send-off, captured as they unfold.',
    slot: 'work-cover-weddings',
    cover: 'uploads/weddings/cover.jpg',
    coverPosition: 'center 80%',
    placeholder: 'Drop a wedding cover photo',
    span: 'wide',
  },
  {
    slug: 'pre-wedding',
    title: 'Bridal Events',
    lede: 'Bridal showers, engagements, rehearsal dinners — the moments leading up.',
    slot: 'work-cover-prewedding',
    cover: 'uploads/pre-wedding/cover.jpg',
    coverPosition: 'center 60%',
    placeholder: 'Drop a bridal events cover photo',
  },
  {
    slug: 'community',
    title: 'Special Events',
    lede: 'Celebrations, gatherings, and brand moments worth remembering.',
    slot: 'work-cover-community',
    cover: 'uploads/community/cover.jpg',
    coverPosition: 'center 70%',
    placeholder: 'Drop a special events cover photo',
  },
  {
    slug: 'film',
    title: 'Film',
    lede: '35 mm frames — grain, light, and a little bit of magic.',
    slot: 'work-cover-film',
    cover: 'uploads/film/cover.jpg',
    coverPosition: 'center 55%',
    placeholder: 'Drop a film photo',
  },
  {
    slug: 'super8',
    title: 'Super 8',
    lede: 'Vintage motion film, straight from the reel.',
    slot: 'work-cover-super8',
    cover: 'uploads/super8/cover.jpg',
    coverPosition: 'center 60%',
    placeholder: 'Drop a Super 8 still',
    comingSoon: true,
  },
];

const WORK_COUPLES = [
  {
    id: 'morgan-chris',
    names: 'Morgan & Chris',
    tag: 'Wedding',
    videos: [
      {
        src: 'uploads/weddings/morgan-chris/morgan-chris-video-01.mp4',
        poster: 'uploads/weddings/morgan-chris/morgan-chris-video-01-poster.jpg',
      },
      {
        src: 'uploads/weddings/morgan-chris/morgan-chris-video-02.mp4',
        poster: 'uploads/weddings/morgan-chris/morgan-chris-video-02-poster.jpg',
      },
    ],
    reelUrl: '',
    reelPhoto: '',
    slots: [],
    photos: [
      'uploads/weddings/morgan-chris/morgan-chris-01.jpg',
      'uploads/weddings/morgan-chris/morgan-chris-02.jpg',
      'uploads/weddings/morgan-chris/morgan-chris-03.jpg',
      'uploads/weddings/morgan-chris/morgan-chris-04.jpg',
      'uploads/weddings/morgan-chris/morgan-chris-05.jpg',
      'uploads/weddings/morgan-chris/morgan-chris-06.jpg',
      'uploads/weddings/morgan-chris/morgan-chris-07.jpg',
      'uploads/weddings/morgan-chris/morgan-chris-08.jpg',
      'uploads/weddings/morgan-chris/morgan-chris-09.jpg',
      'uploads/weddings/morgan-chris/morgan-chris-10.jpg',
      'uploads/weddings/morgan-chris/morgan-chris-11.jpg',
      'uploads/weddings/morgan-chris/morgan-chris-12.jpg',
      'uploads/weddings/morgan-chris/morgan-chris-13.jpg',
      'uploads/weddings/morgan-chris/morgan-chris-14.jpg',
    ],
  },
  {
    id: 'angela-brian',
    names: 'Angela & Brian',
    tag: 'Wedding',
    videos: [
      {
        src: 'uploads/weddings/angela-brian/Video Mar 24 2026, 6 43 23 PM.mp4',
        poster: 'uploads/weddings/angela-brian/angela-brian-video-poster-02.jpg',
      },
      {
        src: 'uploads/weddings/angela-brian/Video Mar 24 2026, 4 43 24 PM.mp4',
        poster: 'uploads/weddings/angela-brian/angela-brian-video-poster-01.jpg',
      },
    ],
    reelUrl: 'https://www.instagram.com/reel/DZLbk-Wy26-/',
    reelPhoto: '',
    slots: [],
    photos: [
      'uploads/weddings/angela-brian/angela-brian-01.jpg',
      'uploads/weddings/angela-brian/angela-brian-02.jpg',
      'uploads/weddings/angela-brian/angela-brian-03.jpg',
      'uploads/weddings/angela-brian/angela-brian-04.jpg',
    ],
  },
  {
    id: 'laney-jimmy',
    names: 'Laney & Jimmy',
    tag: 'Wedding',
    videos: [
      {
        src: 'uploads/weddings/laney-jimmy/Video Sep 30 2025, 4 36 32 PM.mp4',
        poster: 'uploads/weddings/laney-jimmy/Video Sep 30 2025, 4 36 32 PM.mp4.png',
      },
      {
        src: 'uploads/weddings/laney-jimmy/Video Oct 06 2025, 4 08 17 PM.mp4',
        poster: 'uploads/weddings/laney-jimmy/Video Oct 06 2025, 4 08 17 PM.mp4.png',
      },
    ],
    reelUrl: '',
    reelPhoto: '',
    slots: [],
    photos: [
      'uploads/weddings/laney-jimmy/laney-jimmy-01.jpg',
      'uploads/weddings/laney-jimmy/laney-jimmy-02.jpg',
      'uploads/weddings/laney-jimmy/laney-jimmy-05.jpg',
      'uploads/weddings/laney-jimmy/laney-jimmy-06.jpg',
      'uploads/weddings/laney-jimmy/laney-jimmy-07.jpg',
    ],
  },
  {
    id: 'maddie-hayden',
    names: 'Maddie & Hayden',
    tag: 'Wedding',
    videos: [
      {
        src: 'uploads/weddings/maddie-hayden/Video May 31 2026, 6 20 35 PM.mp4',
        poster: 'uploads/weddings/maddie-hayden/Video May 31 2026, 6 20 35 PM.mp4.png',
      },
      {
        src: 'uploads/weddings/maddie-hayden/Video Jun 02 2026, 7 33 37 PM.mp4',
        poster: 'uploads/weddings/maddie-hayden/Video Jun 02 2026, 7 33 37 PM.mp4.png',
      },
    ],
    reelUrl: '',
    reelPhoto: '',
    slots: [],
    photos: [
      'uploads/weddings/maddie-hayden/maddie-hayden-01.jpg',
      'uploads/weddings/maddie-hayden/maddie-hayden-02.jpg',
      'uploads/weddings/maddie-hayden/maddie-hayden-03.jpg',
      'uploads/weddings/maddie-hayden/maddie-hayden-04.jpg',
      'uploads/weddings/maddie-hayden/maddie-hayden-05.jpg',
      'uploads/weddings/maddie-hayden/maddie-hayden-06.jpg',
      'uploads/weddings/maddie-hayden/maddie-hayden-07.jpg',
    ],
  },
  {
    id: 'mari-brandon',
    names: 'Mari & Brandon',
    tag: 'Wedding',
    videos: [
      {
        src: 'uploads/weddings/mari-brandon/Video Jul 02 2026, 12 46 11 PM.mp4',
        poster: 'uploads/weddings/mari-brandon/Video Jul 02 2026, 12 46 11 PM.mp4.png',
      },
      {
        src: 'uploads/weddings/mari-brandon/Video Jul 02 2026, 12 46 58 PM.mp4',
        poster: 'uploads/weddings/mari-brandon/Video Jul 02 2026, 12 46 58 PM.mp4.png',
      },
    ],
    reelUrl: '',
    reelPhoto: '',
    slots: [],
    photos: [
      'uploads/weddings/mari-brandon/mari-brandon-01.jpg',
      'uploads/weddings/mari-brandon/mari-brandon-02.jpg',
      'uploads/weddings/mari-brandon/mari-brandon-03.jpg',
    ],
  },
];

const WORK_PREWEDDING_VIDEOS = [
  {
    src: 'uploads/pre-wedding/Video Jul 04 2026, 2 38 54 PM.mp4',
    poster: 'uploads/pre-wedding/Video Jul 04 2026, 2 38 54 PM.mp4.png',
  },
  {
    src: 'uploads/pre-wedding/Video May 29 2026, 10 46 40 PM.mp4',
    poster: 'uploads/pre-wedding/Video May 29 2026, 10 46 40 PM.mp4.png',
  },
  {
    src: 'uploads/pre-wedding/Video May 29 2026, 11 03 32 PM.mp4',
    poster: 'uploads/pre-wedding/Video May 29 2026, 11 03 32 PM.mp4.png',
  },
];

const WORK_COMMUNITY_VIDEOS = [
  {
    src: 'uploads/community/Video Dec 13 2025, 7 21 02 PM.mp4',
    poster: 'uploads/community/Video Dec 13 2025, 7 21 02 PM.mp4.png',
  },
  {
    src: 'uploads/community/Video Jan 14 2026, 9 38 53 AM.mp4',
    poster: 'uploads/community/Video Jan 14 2026, 9 38 53 AM.mp4.png',
  },
];

const WORK_FILM_PHOTOS = [
  'uploads/film/R1-03451-0012.JPG',
  'uploads/film/R1-03451-0015.JPG',
  'uploads/film/R1-03451-0017.JPG',
  'uploads/film/R1-03451-0021.JPG',
  'uploads/film/R1-03451-0023.JPG',
  'uploads/film/R1-09382-0011.JPG',
  'uploads/film/R1-09382-0013.JPG',
  'uploads/film/R1-09382-0014.JPG',
  'uploads/film/R1-09382-0022.JPG',
  'uploads/film/R1-09382-0025.JPG',
  'uploads/film/R1-09382-0031.JPG',
  'uploads/film/R1-09382-0037.JPG',
];

/* ─── REEL GRID ──────────────────────────────────────────────────
   Equal-tile portrait video grid. The source footage is shot vertically
   (phone/Reels aspect), so forcing it into a 16:9 hero box via object-fit
   crops away most of the frame and reads as an extreme, awkward zoom. A
   row of portrait tiles honors the real aspect ratio and gives every clip
   equal weight. Shared by video-only couples and other video-only
   categories (e.g. Special Events). */
function WorkReelGrid({ videos, idPrefix }) {
  return (
    <div className="reel-grid">
      {videos.map((v, i) => (
        <div className="reel-tile" key={`${idPrefix}-video-${i}`}>
          <VideoAutoPlay src={v.src} poster={v.poster} />
        </div>
      ))}
    </div>
  );
}

/* ─── LIGHTBOX ───────────────────────────────────────────────────
   Tap/click a gallery photo to view it full-screen. Swipe left/right
   (or arrow keys) to move through the gallery; tap the backdrop, the ×,
   or press Escape to close. Rendered through a portal so a transformed
   ancestor (.reveal) can't trap the fixed overlay. */
function Lightbox({ photos, index, onClose, onNav }) {
  React.useEffect(() => {
    const onKey = (e) => {
      if (e.key === 'Escape') onClose();
      else if (e.key === 'ArrowLeft') onNav(-1);
      else if (e.key === 'ArrowRight') onNav(1);
    };
    window.addEventListener('keydown', onKey);
    const prevOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => {
      window.removeEventListener('keydown', onKey);
      document.body.style.overflow = prevOverflow;
    };
  }, [onClose, onNav]);

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

  return ReactDOM.createPortal(
    <div
      className="lightbox"
      role="dialog"
      aria-modal="true"
      aria-label="Photo viewer"
      onClick={onClose}
      onTouchStart={onTouchStart}
      onTouchEnd={onTouchEnd}
    >
      <button className="lightbox-close" aria-label="Close" onClick={onClose}>
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" width="22" height="22">
          <path d="M6 6l12 12M18 6L6 18"></path>
        </svg>
      </button>
      {photos.length > 1 && (
        <button className="lightbox-arrow lightbox-prev" aria-label="Previous photo"
          onClick={(e) => { e.stopPropagation(); onNav(-1); }}>
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" width="26" height="26">
            <path d="M15 18l-6-6 6-6"></path>
          </svg>
        </button>
      )}
      <img
        className="lightbox-img"
        src={photos[index]}
        alt=""
        onClick={(e) => e.stopPropagation()}
      />
      {photos.length > 1 && (
        <button className="lightbox-arrow lightbox-next" aria-label="Next photo"
          onClick={(e) => { e.stopPropagation(); onNav(1); }}>
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" width="26" height="26">
            <path d="M9 6l6 6-6 6"></path>
          </svg>
        </button>
      )}
      {photos.length > 1 && (
        <div className="lightbox-count">{index + 1} / {photos.length}</div>
      )}
    </div>,
    document.body
  );
}

/* Shared open/nav state for any photo gallery that offers enlargement. */
function useLightbox(photos) {
  const [index, setIndex] = React.useState(null);
  const open = (i) => setIndex(i);
  const close = () => setIndex(null);
  const nav = (dir) => setIndex((cur) => (cur + dir + photos.length) % photos.length);
  const lightbox = index != null
    ? <Lightbox photos={photos} index={index} onClose={close} onNav={nav} />
    : null;
  return { open, lightbox };
}

/* ─── COUPLE PHOTOS ──────────────────────────────────────────────
   Candid stills from the day, shown as a horizontally-scrolling filmstrip
   below the video reel. Portrait tiles keep them honest to the source
   (phone-shot verticals) and a scroll rail handles anywhere from a
   couple of photos to a dozen without the grid math changing per couple. */
function WorkCouplePhotos({ photos, names, idPrefix }) {
  const { open, lightbox } = useLightbox(photos || []);
  if (!photos || photos.length === 0) return null;
  return (
    <div className="couple-photos-block">
      <div className="couple-photos-label">Moments from the day</div>
      <div className="couple-photos">
        {photos.map((src, i) => (
          <button
            type="button"
            className="couple-photo photo-zoom"
            key={`${idPrefix}-photo-${i}`}
            onClick={() => open(i)}
            aria-label={`Enlarge ${names} wedding photo ${i + 1}`}
          >
            <img src={src} alt={`${names} wedding photo ${i + 1}`} loading="lazy" />
          </button>
        ))}
      </div>
      {lightbox}
    </div>
  );
}

/* ─── COUPLE CARD ──────────────────────────────────────────────── */
function WorkCoupleCard({ couple }) {
  // Couples with multiple clips carry a `videos` array; older single-clip
  // couples still use `videoSrc`.
  const videos = couple.videos || (couple.videoSrc ? [{ src: couple.videoSrc }] : []);
  const sideSlots = couple.slots || [];
  // Video-only couples (no photo slots at all) get an equal-tile portrait
  // grid instead of the hero+sidebar layout: the source footage is shot
  // vertically (phone/Reels aspect), so forcing it into a 16:9 hero box
  // via object-fit crops away most of the frame and reads as an extreme,
  // awkward zoom. A row of portrait tiles honors the real aspect ratio and
  // gives every clip equal weight.
  const videoOnly = videos.length > 1 && sideSlots.length === 0;

  return (
    <div className="couple-card">
      <div className="couple-card-head">
        <div>
          <div className="couple-tag">{couple.tag}</div>
          <h3 className="couple-name">{couple.names}</h3>
        </div>
        {couple.reelUrl && (
          <a className="couple-reel-link" href={couple.reelUrl} target="_blank" rel="noopener">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" width="15" height="15">
              <rect x="3" y="3" width="18" height="18" rx="5"></rect>
              <circle cx="12" cy="12" r="4"></circle>
            </svg>
            Watch reel
          </a>
        )}
      </div>

      {videoOnly ? (
        <WorkReelGrid videos={videos} idPrefix={couple.id} />
      ) : (
        <div className="couple-media">
          <div className="couple-hero">
            {videos[0] ? (
              <VideoAutoPlay src={videos[0].src} poster={videos[0].poster} />
            ) : (
              <image-slot id={`${couple.id}-hero`} shape="rect" placeholder={`Drop a ${couple.names} video or photo`}></image-slot>
            )}
          </div>
          <div className="couple-slots">
            {videos.slice(1).map((v, i) => (
              <VideoAutoPlay key={`${couple.id}-video-${i}`} src={v.src} poster={v.poster} />
            ))}
            {sideSlots.map(sid => (
              <image-slot key={sid} id={sid} shape="rect" placeholder="Drop a photo"></image-slot>
            ))}
          </div>
        </div>
      )}

      <WorkCouplePhotos photos={couple.photos} names={couple.names} idPrefix={couple.id} />
    </div>
  );
}

/* ─── CATEGORY GALLERIES ───────────────────────────────────────── */
function WorkWeddings() {
  return (
    <div className="weddings-list">
      {WORK_COUPLES.map(c => <WorkCoupleCard key={c.id} couple={c} />)}
    </div>
  );
}

function WorkFilm() {
  const { open, lightbox } = useLightbox(WORK_FILM_PHOTOS);
  return (
    <div className="film-grid">
      {WORK_FILM_PHOTOS.map((src, i) => (
        <div key={src} className="film-slot-wrap">
          <button
            type="button"
            className="film-slot-inner photo-zoom"
            onClick={() => open(i)}
            aria-label={`Enlarge film photo ${i + 1}`}
          >
            <img src={src} alt="" loading="lazy" />
            <div className="film-grain" aria-hidden="true"></div>
          </button>
          <div className="film-slot-number">{String(i + 1).padStart(2, '0')}</div>
        </div>
      ))}
      {lightbox}
    </div>
  );
}

/* ─── SUPER 8 · COMING SOON ────────────────────────────────────── */
function WorkSuper8() {
  return (
    <div className="super8-soon">
      <div className="super8-frame">
        <div className="film-grain" aria-hidden="true"></div>
        <div className="super8-inner">
          <div className="eyebrow super8-eyebrow">Super 8</div>
          <div className="script super8-script">Coming soon</div>
          <p className="super8-copy">
            Something nostalgic is in the works — grainy, flickering, real motion film
            of your day, straight from the reel. Want to be among the first?
          </p>
          <a href="#save" className="btn btn-ghost">Inquire about Super 8 <Icon.Arrow /></a>
        </div>
      </div>
    </div>
  );
}

/* ─── LANDING ──────────────────────────────────────────────────── */
function WorkTile({ cat }) {
  return (
    <a href={`#work/${cat.slug}`} className={`work-tile ${cat.span === 'wide' ? 'work-tile-wide' : ''}`}>
      <div className="work-tile-media">
        {cat.cover ? (
          <img src={cat.cover} alt="" style={cat.coverPosition ? { objectPosition: cat.coverPosition } : undefined} />
        ) : (
          <image-slot id={cat.slot} shape="rect" placeholder={cat.placeholder}></image-slot>
        )}
      </div>
      <div className="work-tile-veil"></div>
      <div className="work-tile-label">
        <span className="script work-tile-script">{cat.title}</span>
        <span className="work-tile-cta">{cat.comingSoon ? 'Coming Soon' : 'View Gallery'}</span>
      </div>
    </a>
  );
}

function WorkLanding() {
  return (
    <>
      <div className="section-head work-head">
        <div className="reveal eyebrow">The Portfolio</div>
        <h1 className="display reveal delay-1">My Work</h1>
        <p className="lede reveal delay-2">
          Every celebration tells its own story. Choose where to begin.
        </p>
      </div>
      <div className="work-tiles reveal delay-2">
        {WORK_CATEGORIES.map(cat => <WorkTile key={cat.slug} cat={cat} />)}
      </div>
    </>
  );
}

/* ─── CATEGORY PAGE SHELL ──────────────────────────────────────── */
function WorkCategory({ cat }) {
  return (
    <>
      <a href="#work" className="work-back">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" width="14" height="14">
          <path d="M19 12H5M11 19l-7-7 7-7"></path>
        </svg>
        My Work
      </a>
      <div className="section-head work-head">
        <div className="reveal eyebrow">The Portfolio</div>
        <h1 className="display reveal delay-1">{cat.title}</h1>
        <p className="lede reveal delay-2">{cat.lede}</p>
      </div>
      {cat.slug === 'weddings'    && <WorkWeddings />}
      {cat.slug === 'pre-wedding' && <WorkReelGrid videos={WORK_PREWEDDING_VIDEOS} idPrefix="pre-wedding" />}
      {cat.slug === 'community'   && <WorkReelGrid videos={WORK_COMMUNITY_VIDEOS} idPrefix="community" />}
      {cat.slug === 'film'        && <WorkFilm />}
      {cat.slug === 'super8'      && <WorkSuper8 />}
    </>
  );
}

/* ─── PAGE ─────────────────────────────────────────────────────── */
function MyWork({ route }) {
  const slug = route.split('/')[1] || '';
  const cat = WORK_CATEGORIES.find(c => c.slug === slug);
  return (
    <section className="work-page" data-screen-label={cat ? `My Work · ${cat.title}` : 'My Work'}>
      <div className="container">
        {cat ? <WorkCategory cat={cat} /> : <WorkLanding />}
      </div>
    </section>
  );
}

window.MyWork = MyWork;
window.WORK_CATEGORIES = WORK_CATEGORIES;
