---
// 縦長の4コマ（1コマ＝縦長1枚 1080×1350）を、横にスワイプして1コマずつ読むビューワー（2026-10-31 第73〜133話から）。
// 4枚とも HTML に出す（JavaScript がなくても横にスクロールして読める・AI や検索にも4枚が見える）。
// JavaScript は「いま何コマ目か」の表示と、前後のボタン・矢印キーだけを受け持つ。
import { media } from '../lib/media';
interface Props { panels: string[]; alts?: string[]; title: string }
const { panels, alts = [], title } = Astro.props;
const n = panels.length;
---
<div class="msw" data-n={n}>
  <div class="msw-track" tabindex="0" role="region" aria-roledescription="carousel" aria-label={`${title}（${n}コマ・横にスワイプして読む）`}>
    {panels.map((p, i) => (
      <figure class="msw-slide" aria-roledescription="slide" aria-label={`${i + 1} / ${n}`}>
        <img src={media(p)} alt={alts[i] || `${title}（${i + 1}コマ目）`} width="1080" height="1350"
          loading={i === 0 ? 'eager' : 'lazy'} decoding="async" draggable="false" />
      </figure>
    ))}
  </div>
  <button class="msw-btn msw-prev" type="button" aria-label="前のコマ" disabled><i class="ms" aria-hidden="true">arrow_back</i></button>
  <button class="msw-btn msw-next" type="button" aria-label="次のコマ"><i class="ms" aria-hidden="true">arrow_forward</i></button>
  <div class="msw-bar"><p class="msw-count" aria-live="polite"><b class="msw-now">1</b><span>/ {n}</span></p></div>
</div>
<script>
  for (const box of document.querySelectorAll<HTMLElement>('.msw')) {
    const track = box.querySelector<HTMLElement>('.msw-track')!;
    const prev = box.querySelector<HTMLButtonElement>('.msw-prev')!;
    const next = box.querySelector<HTMLButtonElement>('.msw-next')!;
    const now = box.querySelector<HTMLElement>('.msw-now')!;
    const n = Number(box.dataset.n) || 1;
    const at = () => Math.round(track.scrollLeft / track.clientWidth);
    // ボタンで送るとき、コマが画面の上下で切れていたら、コマ全体が見える位置まで動かす
    const fit = () => {
      const r = track.getBoundingClientRect();
      const head = 96;
      if (r.top < head || r.bottom > innerHeight) scrollBy({ top: r.top - Math.max(head, (innerHeight - r.height - 64) / 2), behavior: 'smooth' });
    };
    const go = (i: number) => track.scrollTo({ left: Math.max(0, Math.min(n - 1, i)) * track.clientWidth, behavior: 'smooth' });
    const show = () => {
      const i = at();
      now.textContent = String(i + 1);
      prev.disabled = i <= 0;
      next.disabled = i >= n - 1;
    };
    let t = 0;
    track.addEventListener('scroll', () => { cancelAnimationFrame(t); t = requestAnimationFrame(show); }, { passive: true });
    prev.addEventListener('click', () => { fit(); go(at() - 1); });
    next.addEventListener('click', () => { fit(); go(at() + 1); });
    track.addEventListener('keydown', (e) => {
      if (e.key === 'ArrowRight') { e.preventDefault(); go(at() + 1); }
      if (e.key === 'ArrowLeft') { e.preventDefault(); go(at() - 1); }
    });
    show();
  }
</script>
<style>
  /* コマとページャーが1画面に収まる幅にする（縦長 4:5 なので、画面の高さから幅を決める） */
  .msw { position: relative; width: min(100%, calc((100svh - 230px) * 0.8)); min-width: min(100%, 320px); margin: 0 auto; }
  .msw-track {
    display: flex; overflow-x: auto; overflow-y: hidden;
    scroll-snap-type: x mandatory; overscroll-behavior-x: contain;
    scrollbar-width: none; background: #fff;
  }
  .msw-track::-webkit-scrollbar { display: none; }
  .msw-track:focus-visible { outline: 2px solid var(--dark); outline-offset: 2px; }
  .msw-slide { flex: 0 0 100%; margin: 0; scroll-snap-align: start; scroll-snap-stop: always; }
  .msw-slide img { display: block; width: 100%; height: auto; aspect-ratio: 4 / 5; user-select: none; -webkit-user-drag: none; }
  .msw-bar { height: 64px; display: flex; align-items: center; justify-content: center; }
  .msw-count { margin: 0; display: flex; align-items: baseline; gap: 6px; color: var(--ink); }
  .msw-now { font: 600 28px/1 var(--sans); }
  .msw-count span { font: 400 14px/1 var(--sans); color: var(--ink-3); }
  /* ボタン：PC はコマの左右の外（コマの縦の真ん中）、スマホはコマの下の左右 */
  .msw-btn {
    position: absolute; width: 48px; height: 48px; border: 2px solid var(--dark); border-radius: 50%;
    background: #fff; color: var(--dark); cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    top: 0; bottom: 64px; margin: auto 0;
  }
  .msw-prev { left: -80px; }
  .msw-next { right: -80px; }
  .msw-btn .ms { font-size: 24px; }
  .msw-btn:disabled { border-color: #d6d6d6; color: #c4c4c4; cursor: default; }
  @media (max-width: 799px) {
    .msw-btn { top: auto; bottom: 8px; margin: 0; }
    .msw-prev { left: 0; }
    .msw-next { right: 0; }
  }
</style>
