// folio/Lightbox.jsx — full-screen viewer.
// Close by: clicking the image · clicking dark backdrop · ESC · swipe down.
// Navigate by: ← → arrows · keyboard · swipe left/right.

function FolioLightbox({ images, open, index, onClose, onChange }) {
  const trackRef = React.useRef(null);
  const startX = React.useRef(0);
  const startY = React.useRef(0);
  const dragging = React.useRef(false);
  // Tracks whether a swipe gesture just fired so the subsequent click event
  // (browsers emit click after mouseup / touchend) doesn't also close/navigate.
  const swipeHandled = React.useRef(false);

  // Keyboard navigation
  React.useEffect(() => {
    if (!open) return;
    const onKey = (e) => {
      if (e.key === "Escape") onClose();
      if (e.key === "ArrowRight") onChange(Math.min(index + 1, images.length - 1));
      if (e.key === "ArrowLeft")  onChange(Math.max(index - 1, 0));
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open, index, images.length, onChange, onClose]);

  // Body scroll lock
  React.useEffect(() => {
    if (open) {
      const prev = document.body.style.overflow;
      document.body.style.overflow = "hidden";
      return () => { document.body.style.overflow = prev; };
    }
  }, [open]);

  // Touch / mouse swipe
  const onDown = (e) => {
    const p = e.touches ? e.touches[0] : e;
    startX.current = p.clientX;
    startY.current = p.clientY;
    dragging.current = true;
  };
  const onUp = (e) => {
    if (!dragging.current) return;
    dragging.current = false;
    const p = e.changedTouches ? e.changedTouches[0] : e;
    const dx = p.clientX - startX.current;
    const dy = p.clientY - startY.current;
    if (Math.abs(dx) > 60 && Math.abs(dx) > Math.abs(dy)) {
      swipeHandled.current = true;
      if (dx < 0) onChange(Math.min(index + 1, images.length - 1));
      else        onChange(Math.max(index - 1, 0));
    } else if (Math.abs(dy) > 100 && Math.abs(dy) > Math.abs(dx)) {
      swipeHandled.current = true;
      onClose();
    }
  };

  // Clicking the dark backdrop (not an arrow / top / bottom bar) closes.
  const onStageClick = (e) => {
    if (swipeHandled.current) { swipeHandled.current = false; return; }
    if (e.target.closest(".lb-arrow, .lb-btn, .lb-bottom, .lb-top")) return;
    onClose();
  };

  // Clicking the image (any device) closes the lightbox.
  // Use arrows or swipe left/right to navigate between photos.
  const onFrameClick = (e) => {
    e.stopPropagation();
    if (swipeHandled.current) { swipeHandled.current = false; return; }
    onClose();
  };

  const stopProp = (e) => e.stopPropagation();

  if (!images || images.length === 0) return null;
  const img = images[index] || images[0];
  const pct = ((index + 1) / images.length) * 100;

  return ReactDOM.createPortal(
    <div className={classes("folio-lb", open && "open")}
         role="dialog" aria-modal="true" aria-label="Photo viewer"
         aria-hidden={!open}
         onClick={onClose}>
        {open && <button className="lb-close-x" onClick={onClose} aria-label="Close gallery">×</button>}

      {/* Top bar */}
      <div className="lb-top" onClick={stopProp}>
        <div className="left">
          <span className="folio-mark" style={{ color: "var(--wn-cream)", fontSize: 13 }}>
            WONAMU<span className="dot">.</span>
          </span>
          <span className="lb-eyebrow">{img.cat}</span>
        </div>
        <div className="right">
          <span className="lb-counter">
            {String(index + 1).padStart(2, "0")} / {String(images.length).padStart(2, "0")}
          </span>
          <button className="lb-btn" onClick={onClose}>Close ✕</button>
        </div>
      </div>

      {/* Stage */}
      <div className="lb-stage"
           onClick={onStageClick}
           onMouseDown={onDown} onMouseUp={onUp}
           onTouchStart={onDown} onTouchEnd={onUp}>

        <button className="lb-arrow prev"
                onClick={(e) => { stopProp(e); onChange(Math.max(index - 1, 0)); }}
                disabled={index === 0}
                aria-label="Previous">◀</button>
        <button className="lb-arrow next"
                onClick={(e) => { stopProp(e); onChange(Math.min(index + 1, images.length - 1)); }}
                disabled={index === images.length - 1}
                aria-label="Next">▶</button>

        <div ref={trackRef} className="lb-track" style={{ "--lb-i": index }}>
          {images.map((it, i) => (
            <div key={it.id} className="lb-slide">
              {/* Click the frame/image to close */}
              <div className="frame lb-frame-close" style={{ aspectRatio: it.ratio }} onClick={onFrameClick}>
                {Math.abs(i - index) <= 1 ? (
                  <FolioPhoto img={it} big eager={i === index} />
                ) : (
                  <FolioSwatch img={it} big />
                )}
              </div>
            </div>
          ))}
        </div>
      </div>

      {/* Bottom bar */}
      <div className="lb-bottom" onClick={stopProp}>
        <div>
          <div className="title">{img.title}</div>
          <div className="desc">{img.caption}</div>
        </div>
        <div className="side">
          <div>{img.no}</div>
          <div style={{ marginTop: 4, opacity: 0.6 }}>{img.cat}</div>
        </div>
      </div>

      <div className="lb-progress"><span style={{ width: pct + "%" }} /></div>
      <div className="lb-hint">swipe ← → to browse &nbsp;·&nbsp; ↓ to close</div>
    </div>,
    document.body
  );
}

Object.assign(window, { FolioLightbox });
