// Article page: masthead, drop-cap body, shop the story, continue reading.

const { useEffect, useState: useStateArt, useRef } = React;

function ArticlePage({ article, allEntries, onOpenArticle, onNav }) {
  const [progress, setProgress] = useStateArt(0);
  const bodyRef = useRef(null);

  useEffect(() => {
    const handler = () => {
      const el = bodyRef.current;
      if (!el) return;
      const rect = el.getBoundingClientRect();
      const total = el.offsetHeight - window.innerHeight;
      const scrolled = Math.max(0, -rect.top);
      const pct = Math.min(1, total > 0 ? scrolled / total : 0);
      setProgress(pct);
    };
    window.addEventListener("scroll", handler, { passive: true });
    handler();
    return () => window.removeEventListener("scroll", handler);
  }, [article.slug]);

  const lensKanji = { history: "歴", craftsman: "職", material: "素", reinterpretation: "解" };
  const lensLabel = { history: "History", craftsman: "Craftsman", material: "Material", reinterpretation: "Reinterpretation" };

  return (
    <div className="page-fade-enter" ref={bodyRef}>
      <div className="article-shell">
        <div className="article-meta-bar">
          <div className="article-meta-bar__breadcrumb">
            <a href="#" onClick={(e) => { e.preventDefault(); onNav("cover"); }}>Volume I · 2026</a>
            <span className="sep">/</span>
            <span>{article.desk}</span>
            <span className="sep">/</span>
            <span style={{ color: "var(--color-ink-deep)" }}>No. {String(article.n).padStart(2, "0")}</span>
          </div>
          <div className="article-meta-bar__progress">
            <span>Reading</span>
            <div className="article-meta-bar__progress-track">
              <div
                className="article-meta-bar__progress-fill"
                style={{ transform: `scaleX(${progress})` }}
              />
            </div>
            <span>{Math.round(progress * 100)}%</span>
          </div>
        </div>

        <div className="article-grid">
          <aside className="article-aside">
            <dl>
              <dt>Lens</dt>
              <dd>
                <span className="article-aside__lens" lang="ja">
                  {lensKanji[article.lens]}
                </span>
                {lensLabel[article.lens]}
              </dd>
              <dt>Desk</dt>
              <dd>{article.desk}</dd>
              <dt>Published</dt>
              <dd>{article.publishedAt}</dd>
              <dt>Reading time</dt>
              <dd>≈ {article.readingMin} minutes</dd>
              <dt>Word count</dt>
              <dd>{article.words.toLocaleString()} words</dd>
              <dt>Volume</dt>
              <dd>I · 2026</dd>
              <dt>Filed from</dt>
              <dd>Tokyo</dd>
            </dl>
          </aside>

          <main className="article-main">
            <header>
              <p className="article-header__eyebrow">
                {article.desk}
              </p>
              <h1 className="article-header__title">{article.title}</h1>
              <p className="article-header__deck">{article.deck}</p>
              <div className="article-header__byline">
                <span className="author">{article.author}</span>
                <span>{article.publishedAt}</span>
                <span>{article.readingMin} min read</span>
              </div>
              <p className="article-disclosure">
                This article contains affiliate links. 本記事はアフィリエイト広告を含みます。 The round is not a commission — see <a style={{ color: "var(--color-accent-primary)" }} href="#">Disclosure</a>.
              </p>
            </header>

            <figure className="article-hero article-hero--img">
              <img
                src="https://images.unsplash.com/photo-1535131749006-b7f58c99034b?w=1800&q=80&auto=format&fit=crop"
                alt=""
                loading="lazy"
              />
              <figcaption>
                <span className="num">Plate I.</span>
                A twelve-gauge cashmere, photographed in the locker room at Koganei.
              </figcaption>
            </figure>

            <div className="article-body">
              <p>
                A good cashmere does not announce itself. You notice it, if at all, in the third hole — when the shoulder turn arrives without resistance and the sleeve returns to its fall without a twist. That is the quiet test. Everything before the round, and most of what is written about it, is noise.
              </p>
              <p>
                The knit that passes this test is almost always a twelve-gauge, finished slowly, from a fibre whose length has not been compromised by the speed of the market. There are perhaps forty houses in the world still making it this way. A half-dozen serve Tokyo directly. This Issue is concerned only with those.
              </p>

              <h2>
                <span className="num">§ 01</span>
                On the gauge, and why it matters
              </h2>
              <p>
                Gauge is stitch count per inch. A <em className="kanji">十二</em>-gauge knit — twelve stitches — sits at the threshold where a sweater becomes a jumper and a jumper becomes a layer. Finer and it is underwear; coarser and it is outerwear. For the course, twelve is the number.
              </p>
              <p>
                The Roadster from Loro Piana, the two-tone ribbed from Brunello Cucinelli, and the Sea Island Bobby from John Smedley all sit in or adjacent to this window. They are not the same garment. They are three answers to the same question, asked by three houses that have been asking it for, respectively, one hundred and two, forty-eight, and two hundred and forty-two years.
              </p>

              <blockquote>
                "A twelve-gauge is the quietest a knit can be and still be a knit. Finer, and it stops being a sweater. Coarser, and it stops being a shoulder."
                <cite>— Master knitter, Biella, 2025</cite>
              </blockquote>

              <h2>
                <span className="num">§ 02</span>
                The length of the fibre
              </h2>
              <p>
                A cashmere's worth is not decided in the mill but on the goat. The under-hairs of an Alashan or Inner Mongolian animal, combed (not shorn) in early spring, run thirty-six to forty millimetres. Australian or Iranian fibre runs shorter. The long fibre is what survives twenty years of wear; the short fibre is what pills in eighteen months and is written off as a lesson.
              </p>
              <p>
                The houses that matter list a fibre length. Most do not. That omission, quietly, is the answer to the question you were going to ask them.
              </p>

              <figure className="inline-block">
                <div className="label">Editor's note · 素材</div>
                A piece that will not pill after a year of Saturday rounds is a piece cut from forty-millimetre fibre, knitted at twelve gauge, finished on a linking machine that takes twenty minutes rather than forty seconds. None of this is visible from the rack. All of it is visible in the garment, after twelve months.
              </figure>

              <h2>
                <span className="num">§ 03</span>
                Three answers, one round
              </h2>
              <p>
                Below, three pieces we have worn for at least one full Tokyo season each. None are sponsored; none were sent. All were bought at retail, at the Marunouchi and Aoyama flagships listed. The retailer matters because the after-sale matters: a resole, a reknit, a quiet reweave of a snagged thread.
              </p>
              <p>
                The shortest answer is always the best one. Buy once. Wear the piece for ten years. Return it to the house that made it when it needs a second life. This is what the houses below are built to do, and what the prices, quietly, reflect.
              </p>
            </div>

            <section className="shop-the-story">
              <header className="shop-the-story__head">
                <p className="shop-the-story__kicker">Shop the Story</p>
                <h3>The pieces that earned the page.</h3>
                <p className="shop-the-story__deck">
                  A short, editor-led selection. No rankings. Each is available at
                  the Tokyo retailer listed — click through for current stock.
                </p>
              </header>

              <div className="shop-grid">
                {article.shopProducts.map((p, i) => {
                  const imgs = [
                    "https://images.unsplash.com/photo-1535132011086-b8818f016104?w=800&q=80&auto=format&fit=crop",
                    "https://images.unsplash.com/photo-1551803091-e20673f15770?w=800&q=80&auto=format&fit=crop",
                    "https://images.unsplash.com/photo-1593111774240-d529f12cf4bb?w=800&q=80&auto=format&fit=crop",
                  ];
                  return (
                  <div className="product-card" key={i}>
                    <div className="product-card__media product-card__media--img">
                      <img src={imgs[i % 3]} alt="" loading="lazy" />
                    </div>
                    <div className="product-card__brand">{p.brand}</div>
                    <div className="product-card__name">{p.name}</div>
                    <div className="product-card__row">
                      <span>{p.tag}</span>
                      <span className="product-card__price">{p.price}</span>
                    </div>
                    <div className="product-card__cta">
                      <span>At {p.retailer.split(",")[1]?.trim() || p.retailer}</span>
                      <span>→</span>
                    </div>
                  </div>
                  );
                })}
              </div>
            </section>

            <section className="continue">
              <p className="continue__head">Continue reading</p>
              <ul className="continue__list">
                {article.related.map((r) => (
                  <li
                    key={r.slug}
                    className="continue__item"
                    onClick={() => {
                      window.scrollTo({ top: 0 });
                      onOpenArticle(r.slug);
                    }}
                  >
                    <div className="continue__desk">{r.desk}</div>
                    <div className="continue__title">{r.title}</div>
                  </li>
                ))}
              </ul>
            </section>
          </main>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { ArticlePage });
