// Case detail — Figma layout: static left bar with text + credits, scrollable right column with media

const DESC_CHAR_LIMIT = 360;

function CaseView({ id, navigate }) {
  const cases = window.CASES;
  const [readMore, setReadMore] = React.useState(false);
  const idx = cases.findIndex((c) => c.id === id);

  // Reset the modal whenever the case changes
  React.useEffect(() => { setReadMore(false); }, [id]);

  if (idx === -1) {
    return (
      <main className="case-view case-404">
        <p>Case not found.</p>
        <a href="#/" onClick={(e) => { e.preventDefault(); navigate("/"); }} className="back-link">Index</a>
      </main>
    );
  }
  const c = cases[idx];
  const next = cases[(idx + 1) % cases.length];
  const prev = cases[(idx - 1 + cases.length) % cases.length];

  // Build a gallery: lead with the case's main media (or a page-specific override), then case-specific gallery items.
  const lead = c.pageMedia || c.media;
  const galleryItems = [
    { kind: lead.kind, src: lead.src, tone: lead.tone, layout: "full", videoAr: lead.videoAr, controls: lead.controls },
    ...(c.gallery || []),
  ];

  const fullText = c.description || c.summary;
  const descLimit = c.descLimit || DESC_CHAR_LIMIT;
  const isLong = fullText.length > descLimit;
  // Truncate at a word boundary
  const truncated = isLong
    ? fullText.slice(0, descLimit).replace(/\s+\S*$/, "") + "…"
    : fullText;

  return (
    <main className="case-view">
      <div className="case-layout">

        {/* ─── Left sidebar (sticky) ─── */}
        <aside className="case-sidebar">
          <h1 className="case-hero-title">{c.title}</h1>
          <div className="case-hero-line">
            <span>{c.client}</span>
            <span className="dot">·</span>
            <span>{c.year}</span>
          </div>

          {fullText && <p className="case-description">
            {isLong ? (
              (() => {
                const paras = truncated.split("\n\n");
                return paras.map((para, i) => (
                  <React.Fragment key={i}>
                    {i > 0 && <><br /><br /></>}
                    {para}
                    {i === paras.length - 1 && (
                      <>
                        {" "}
                        <button
                          type="button"
                          className="read-more-btn"
                          onClick={() => setReadMore(true)}
                        >Read more</button>
                      </>
                    )}
                  </React.Fragment>
                ));
              })()
            ) : (
              fullText.split("\n").map((line, i) => (
                <React.Fragment key={i}>
                  {i > 0 && <br />}
                  {line}
                </React.Fragment>
              ))
            )}
          </p>}

          {c.descNote && <p className="case-description case-description-note"><em>{c.descNote}</em></p>}

          {c.credits && c.credits.length > 0 && (
            <ul className="case-credits">
              {c.credits.map((name, i) => (
                <li key={i} className="case-credit">{name}</li>
              ))}
            </ul>
          )}

          <nav className="case-pager case-pager-desktop">
            <a
              href={`#/work/${prev.id}`}
              onClick={(e) => { e.preventDefault(); navigate(`/work/${prev.id}`); }}
              className="pager-link pager-prev"
            >
              <span className="pager-label">Previous</span>
              <span className="pager-title">{prev.title}</span>
            </a>
            <a
              href={`#/work/${next.id}`}
              onClick={(e) => { e.preventDefault(); navigate(`/work/${next.id}`); }}
              className="pager-link pager-next"
            >
              <span className="pager-label">Next</span>
              <span className="pager-title">{next.title}</span>
            </a>
          </nav>
        </aside>

        {/* ─── Right column (scrolling media) ─── */}
        <section className="case-media-col">
          <GalleryGrid items={galleryItems} />

          {/* Mobile-only pager: sits below all media */}
          <nav className="case-pager case-pager-mobile">
            <a
              href={`#/work/${prev.id}`}
              onClick={(e) => { e.preventDefault(); navigate(`/work/${prev.id}`); }}
              className="pager-link pager-prev"
            >
              <span className="pager-label">Previous</span>
              <span className="pager-title">{prev.title}</span>
            </a>
            <a
              href={`#/work/${next.id}`}
              onClick={(e) => { e.preventDefault(); navigate(`/work/${next.id}`); }}
              className="pager-link pager-next"
            >
              <span className="pager-label">Next</span>
              <span className="pager-title">{next.title}</span>
            </a>
          </nav>
        </section>

      </div>

      {readMore && (
        <ReadMoreModal
          title={c.title}
          text={fullText}
          note={c.descNote}
          onClose={() => setReadMore(false)}
        />
      )}
    </main>
  );
}

// Full-text modal triggered by "Read more"
function ReadMoreModal({ title, text, note, onClose }) {
  React.useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", onKey);
    // Lock every possible scroll container across layouts: the <html> element
    // (mobile/tablet, < 1100px), the <body>, and the case page's internal
    // scroll column (desktop, >= 1100px).
    const scroller = document.querySelector(".case-media-col");
    const html = document.documentElement;
    const prevHtml = html.style.overflow;
    const prevBody = document.body.style.overflow;
    const prevScroller = scroller ? scroller.style.overflow : "";
    html.style.overflow = "hidden";
    document.body.style.overflow = "hidden";
    if (scroller) scroller.style.overflow = "hidden";

    // Belt-and-suspenders: swallow scroll gestures that don't land inside the
    // dialog, and contain the dialog's own scroll at its edges so nothing
    // chains through to the page behind it. Works regardless of which element
    // the browser would otherwise scroll.
    const inDialog = (target) => {
      const d = document.querySelector(".readmore-dialog");
      return d && d.contains(target);
    };
    const onWheel = (e) => {
      const d = document.querySelector(".readmore-dialog");
      if (d && d.contains(e.target)) {
        const atTop = d.scrollTop <= 0;
        const atBottom = d.scrollTop + d.clientHeight >= d.scrollHeight - 1;
        if ((atTop && e.deltaY < 0) || (atBottom && e.deltaY > 0)) e.preventDefault();
        return;
      }
      e.preventDefault();
    };
    const onTouchMove = (e) => { if (!inDialog(e.target)) e.preventDefault(); };
    document.addEventListener("wheel", onWheel, { passive: false });
    document.addEventListener("touchmove", onTouchMove, { passive: false });

    return () => {
      document.removeEventListener("keydown", onKey);
      document.removeEventListener("wheel", onWheel, { passive: false });
      document.removeEventListener("touchmove", onTouchMove, { passive: false });
      html.style.overflow = prevHtml;
      document.body.style.overflow = prevBody;
      if (scroller) scroller.style.overflow = prevScroller;
    };
  }, [onClose]);

  return (
    <div className="readmore-overlay" onClick={onClose}>
      <div className="readmore-dialog" role="dialog" aria-modal="true" onClick={(e) => e.stopPropagation()}>
        <button type="button" className="readmore-close" onClick={onClose} aria-label="Close">×</button>
        <h2 className="readmore-title">{title}</h2>
        <div className="readmore-body">
          {text.split("\n\n").map((para, i) => (
            <p key={i}>{para}</p>
          ))}
          {note && <p><em>{note}</em></p>}
        </div>
      </div>
    </div>
  );
}

// Pack media items into a 12-col grid based on each item's `layout` ('full' | 'half' | 'third')
function GalleryGrid({ items }) {
  return (
    <div className="case-gallery">
      {items.map((it, i) => {
        const span =
          it.layout === "third" ? "span-4" :
          it.layout === "half"  ? "span-6" : "span-12";
        const aspect =
          it.videoAr ? it.videoAr.replace("/", " / ") :
          it.layout === "half"  ? "1 / 1" :
          it.layout === "third" ? "1 / 1" : "1093 / 615";
        return (
          <div
            key={i}
            className={`case-gallery-item ${span}${it.src && it.kind === "image" ? " has-image" : ""}`}
            style={{ "--g-aspect": aspect }}
          >
            <window.MediaPlaceholder kind={it.kind} tone={it.tone} src={it.src} videoAr={it.videoAr} controls={it.controls} />
          </div>
        );
      })}
    </div>
  );
}

window.CaseView = CaseView;
