/* tenroin-top/magazine.jsx — READING LIFE の自前トップ（`/magazine` の一枚・D'）
   出典＝2026/9/7 12:12 CTO 指示。意匠は 9/6 の意匠手帳「誌面の棚」（代表 E8 の決定）。
   ★この頁は**器だけ**を持つ。中身の部品は articles.jsx の一箇所を見る
     （`RlRack` ＝ 三誌の棚と戸口 ／ `RlBanzuke` ＝ 番付）。写しを作らない。
   ★数は台帳が正。日刊の一行は `/api/magazine/daily/latest`、週刊の回数は掛かっている放送、
     本誌の号名は ISSUE.ja から。ここでは**一つも焼かない**。
   ★API は増やしていない。 */
/* ── ヒーロー（月替わりのキービジュアル）── 代表指示 2026/9/7 19:2x（CTO 19:23 経由）
   「ウェブリーディングライフもヒーロー部分が必要。かっこいい画像が必要。月ごとに変わってもいい」

   ★白い紙面の意匠は保つ（黒い地にしない＝2026/9/7 代表の字）。
   ★**絵は暦で選ぶ。焼かない。** その月の絵が無ければ**直近の一枚**へ下がり、
     一枚も無ければ**絵の器ごと出さない**（壊れた画像を出すより、題字だけのほうがよい）。
   ★字も約束を増やさない ── その月の一行が無ければ**号の題**（ISSUE.theme）を使う。
     ⚠️新しい文句をここで作らない（号の題は articles.jsx の一箇所が正本）。
   ★戸口（日刊・週刊・本誌）は**棚のまま**。ここには置かない（二重の入口を作らない）。

   ■ 月を足すときの手順（次にこの頁を触る人へ）
     1. `assets/rl-hero-YYYY-MM.jpg` を置く（長辺 1600・JPEG）
     2. 下の `HERO_MONTHS` に 'YYYY-MM' を**一つ足す**（昇順で持つ）
     3. その月の一行が要るなら `HERO_LINES` に足す（要らなければ号の題が出る）
   ⚠️ここに月を書くのは「絵が在る月の名簿」であって、暦ではない。
     **在りもしない絵の月を足すと、その月から絵が割れる。** */

/** 絵が在る月（昇順）。⚠️`assets/rl-hero-<この字>.jpg` が実在する月だけを書く。 */
const HERO_MONTHS = ['2026-09'];

/** その月の一行。無い月は号の題（ISSUE.theme）が出る。 */
const HERO_LINES = {};

/** いまの月（JST）。 */
function heroMonthNow(){
  /* ⚠️閲覧者の機の時計ではなく **JST の暦**で数える（誌面の月は日本の月）。 */
  const jst = new Date(new Date().toLocaleString('en-US', { timeZone: 'Asia/Tokyo' }));
  return jst.getFullYear() + '-' + String(jst.getMonth() + 1).padStart(2, '0');
}

/** その月に出す絵。**その月以前でいちばん新しい一枚**。一枚も無ければ null。 */
function heroPick(month){
  let hit = null;
  for (let i = 0; i < HERO_MONTHS.length; i++) {
    if (HERO_MONTHS[i] <= month) hit = HERO_MONTHS[i];
  }
  return hit;
}

/* 題の一行を、**読点の後だけで折る**形に組み直す（CTO 2026/9/7 21:13＝代表の画面で
   「クリエイターのための町「天／狼院楽市」、ついにオープン。」と**語の中で折れていた**）。

   ★この repo に既に在る作法を写す（近似を作らない）＝`.lp-seg`／`.nf-seg`＝
     塊を `inline-block` にして、折れる場所を塊の切れ目に寄せる。
   🔴ただし **`white-space:nowrap` は当席の一段目には当てられない** ──
     一段目「クリエイターのための町「天狼院楽市」、」は 19字あり、320px では器より広い。
     nowrap にすると**狭い幅で溢れる**（今日 .rack-item で踏んだのと同じ型）。
   ✅だから二段構え ──
     ① 読点（、）と句点（。）の**後ろ**で塊に割り、塊を `inline-block`（nowrap は当てない）
        ＝ 折れる場所が在れば読点の後が選ばれ、無ければ塊の中で折れる（狭い幅でも溢れない）
     ② 🔴**鉤括弧の中だけ nowrap**（「天狼院楽市」＝6字・320 でも器に収まる）
        ＝ 実際に折れていたのはここ。**固有名の中では折らない**
   ⚠️字は一字も変えない（`ISSUE.theme` が正本）。**組み方だけを変える**。 */
function heroLineParts(line){
  const s = String(line || '');
  if (!s) return [];
  /* ① 読点・句点の後ろで割る（区切り記号は前の塊に残す＝行頭に句読点を置かない） */
  const segs = [];
  let buf = '';
  for (const ch of s) {
    buf += ch;
    if (ch === '、' || ch === '。') { segs.push(buf); buf = ''; }
  }
  if (buf) segs.push(buf);
  /* ② 各塊の中で、鉤括弧に囲まれた所だけを折れない塊にする */
  return segs.map(function(seg){
    const parts = [];
    const re = /「[^」]*」/g;
    let last = 0, m;
    while ((m = re.exec(seg)) !== null) {
      if (m.index > last) parts.push({ nb: false, t: seg.slice(last, m.index) });
      parts.push({ nb: true, t: m[0] });
      last = m.index + m[0].length;
    }
    if (last < seg.length) parts.push({ nb: false, t: seg.slice(last) });
    return parts;
  });
}

function MagazineHero(){
  const ISSUE = (window.MAG || {}).ISSUE || {};
  const month = heroMonthNow();
  const pick = heroPick(month);
  const line = HERO_LINES[month] || ISSUE.theme || '';
  return (
    <div className={'mgz-hero' + (pick ? '' : ' is-plain')}>
      {pick && (
        <div className="mgz-hero-art">
          {/* ⚠️読めなかったら器ごと畳む＝壊れた画像の枠を出さない。 */}
          <img src={'assets/rl-hero-' + pick + '.jpg'} alt="" loading="eager" decoding="async"
               onError={function(e){ const w = e.target.closest('.mgz-hero-art'); if (w) w.remove(); }}/>
        </div>
      )}
      <div className="mgz-hero-in">
        <p className="mgz-hero-mast">READING LIFE</p>
        {line ? (
          <h1 className="mgz-hero-line">
            {heroLineParts(line).map(function(seg, i){
              return (
                <span className="mgz-seg" key={i}>
                  {seg.map(function(pt, j){
                    return pt.nb
                      ? <span className="mgz-nb" key={j}>{pt.t}</span>
                      : <React.Fragment key={j}>{pt.t}</React.Fragment>;
                  })}
                </span>
              );
            })}
          </h1>
        ) : null}
      </div>
    </div>
  );
}

function MagazinePage(){
  const { ISSUE } = window.MAG;
  const RlRack = window.RlRack, RlBanzuke = window.RlBanzuke;
  return (
    <main className="mgz">
      <MagazineHero/>
      {/* 眉・大見出し・前書きは落とした（代表 2026/9/7 15:33）。
          棚の帯（`.rack-mast`＝READING LIFE ── 海の出版社 ── 港の雑誌社 ── 日付）が、この頁の題字。 */}
      <div className="wrap mgz-sec">{RlRack ? <RlRack rich/> : null}</div>

      <div className="wrap mgz-sec">{RlBanzuke ? <RlBanzuke framed/> : null}</div>

      {/* 書庫の戸口（CTO 2026/9/7 13:06 ③）。見開きと一緒に消えた入口を、実在の住所で戻す。
          ★数は台帳（window.MIURA_ARCHIVE）から数える。**読めないときは節ごと出さない**（0 と嘘をつかない）。
          ★住所は一件ずつの実在の読み口（/magazine/<slug>）。索引の頁は無いので作らない。 */}
      {(function(){
        const A = window.MIURA_ARCHIVE;
        if (!Array.isArray(A) || A.length === 0) return null;
        /* 年代別の書庫（代表 2026/9/12「年代別に分けることはできますか。歴史が積み上がって
           いくのが分かるようなのがいい」／年の呼び方は西暦＝代表裁定）。
           ★数はすべて台帳から数える。焼かない。
           ★書いていなかった年も細い線で残す ── 空白も歴史のうちなので飛ばさない。
           ★98本ぜんぶ並べる（ここは書庫＝全部が在る場所）。 */
        const byYear = {};
        A.forEach(function(n){ var y = String(n.d).slice(0,4); (byYear[y] = byYear[y] || []).push(n); });
        const years = Object.keys(byYear).sort();              /* 古い順＝積み上がって見える */
        const y0 = Number(years[0]), y1 = Number(years[years.length - 1]);
        const span = [];
        for (var yy = y0; yy <= y1; yy++) span.push(String(yy)); /* 空白の年も並びに入れる */
        const peak = Math.max.apply(null, years.map(function(y){ return byYear[y].length; }));
        return (
          <div className="wrap mgz-sec mgz-archive">
            <h2 className="mgz-arch-h">書庫 ── 天狼院通信</h2>
            <p className="mgz-arch-lead">
              店主・三浦崇典が書き継いだ全{A.length}本。{years[0]}年から{years[years.length-1]}年まで、{y1 - y0 + 1}年分。
            </p>

            {/* 年の帯 ── 棒の高さがその年に書かれた数。押すとその年へ飛ぶ。 */}
            <div className="mgz-years">
              {span.map(function(y){
                const list = byYear[y];
                const n = list ? list.length : 0;
                return list ? (
                  <a className="mgz-yr" key={y} href={'#tsushin-' + y} aria-label={y + '年 ' + n + '本'}>
                    <span className="myr-bar"><span style={{height:(n / peak * 100) + '%'}}></span></span>
                    <span className="myr-n">{n}</span>
                    <span className="myr-y">{y}</span>
                  </a>
                ) : (
                  <span className="mgz-yr is-none" key={y} aria-label={y + '年 なし'}>
                    <span className="myr-bar"></span>
                    <span className="myr-n">―</span>
                    <span className="myr-y">{y}</span>
                  </span>
                );
              })}
            </div>

            {years.map(function(y){
              return (
                <div className="mgz-yrsec" key={y} id={'tsushin-' + y}>
                  <div className="mgz-yrh"><span className="myh-y">{y}</span><span className="myh-n">{byYear[y].length}本</span></div>
                  <ul className="mgz-arch-list">
                    {byYear[y].map(function(n){
                      return (
                        <li key={n.slug}>
                          {/* 落款＝第一層のスキル。札を持たない本では何も描かれない。
                              ★一覧では第二層（形）の札を出さない ── 一行が窮屈になるため。 */}
                          {window.RlSeal ? <window.RlSeal art={n} /> : null}
                          <a href={'/magazine/' + n.slug} data-cta="mgz-archive">{n.t}</a>
                          <span>{n.d}</span>
                        </li>
                      );
                    })}
                  </ul>
                </div>
              );
            })}
          </div>
        );
      })()}

      <div className="wrap mgz-foot">
        <a href="/tenroin-top/" data-cta="mgz-top">天狼院書店のトップへ</a>
        <span>{ISSUE ? 'READING LIFE ── ' + ISSUE.ja : 'READING LIFE'} ／ 海の出版社</span>
      </div>
    </main>
  );
}

(function(){
  const el = document.getElementById('mgz-root');
  if (el && window.ReactDOM && window.ReactDOM.createRoot) {
    window.ReactDOM.createRoot(el).render(<MagazinePage/>);
  }
})();
