// prologue.jsx
// "PROLOGUE / ストーリー" section.
// Shown ABOVE the GymLeaders section.
// 3 main characters, each with an autoplaying .mp4 portrait.
// One character is "featured" at a time; auto-advances every 10 seconds.

const PROLOGUE_CHARS = [
{
  id: 'kokoha',
  epNo: '01',
  role: '主人公 / 中学生',
  classJa: '見習い保全士',
  name: '日向 心羽',
  yomi: 'ひなた ここは',
  age: 'NABI ID#0518',
  blurb: '失踪した母「海空(みそら)」を追い続ける14歳。\n初のシールドエンブレムを取得し、見習い保全士として、ゲノムレンズを手に旅へ出る。',
  emblems: 1,
  video: 'assets/story-kokoha.mp4',
  poster: 'assets/story-kokoha-poster.jpg',
  accent: '#FFC21A'
},
{
  id: 'rui',
  epNo: '02',
  role: 'NABI 保全士',
  classJa: '正保全士',
  name: '神代 類',
  yomi: 'かみしろ るい',
  age: 'NABI ID#0421',
  blurb: 'スター保全士を志す、心羽の旅のパートナー。\n冷静沈着で、知識は折り紙付き。高校生で正保全士になった、NABI期待の若手。',
  emblems: 5,
  video: 'assets/story-rui.mp4',
  poster: 'assets/story-rui-poster.jpg',
  accent: '#4FA3D1'
},
{
  id: 'misora',
  epNo: '03',
  role: '伝説 / 心羽の母',
  classJa: 'スター保全士',
  name: '日向 海空',
  yomi: 'ひなた みそら',
  age: 'STATUS: MISSING',
  blurb: '「まだ見ぬ生き物を守る」と告げ、6年前に失踪。\nNABI設立期の最前線を駆け抜けた3代目スター保全士。\n国民からの人気が高く慕われている。',
  emblems: '?',
  video: 'assets/story-misora.mp4',
  poster: 'assets/story-misora-poster.jpg',
  accent: '#E6421A'
}];


const PROLOGUE_SYNOPSIS = [
'人類はついにAGI（汎用人工知能）を産業ロボットに宿らせた。だがその代償は重かった――レアメタルを求めて掘り尽くされる山、乱立する小型原発と無秩序なメガソーラー、住民の声を無視して張り巡らされる送電網、そして守られなかったパリ協定における「1.5度目標」。',
'海ではサンゴが白く朽ち、森林火災は常態化、日本は熱帯の気候帯となった。動物たちの逃げ場は日ごとに細り、やがてコロナを超える大疫病が世界を襲う。',
'崩壊する生態系を前に、日本政府は環境省の外郭団体として「国立先進生物多様性機構（NABI）」を設立。最前線に立つ\u201C保全士\u201Dたちは、遺伝子情報をスキャンするだけで生命を取り込み、いつでもそのデータを呼び出せる装置――ゲノムレンズを手に、消えゆく命の最後の砦として活動をしていた。',
'2048年、灼熱化した日本。中学生の日向 心羽（ひなた ここは）は、伝説のスター保全士の母・海空（みそら）が「まだ見ぬ生き物を守る」と告げて失踪したまま、6年の歳月を過ごしていた。',
'そんな時、「インベーダー4」が動き出す。地球史上6度目の――しかも\u201C大量絶滅\u201Dならぬ\u201C完全絶滅\u201Dを企み、人類だけの世界を作るため、生き物を次々と消し去っていく。',
'母が残したカードを手にした心羽（ここは）は、スター保全士を目指す、保全士・類（るい）と共に旅立つ。',
'これは、傷ついた地球が、生物多様性が、もう一度息を吹き返すまでの物語。'];


function PrologueCharCard({ c, isActive, index, onActivate }) {
  const videoRef = React.useRef(null);

  // Only the ACTIVE card decodes a video. Inactive cards detach their
  // source (releasing the hardware decoder) and fall back to a poster
  // image. This avoids the concurrent-decoder limit that left the
  // 2nd/3rd autoplaying videos black on some production browsers, and
  // guarantees a still image instead of a black frame if decode fails.
  React.useEffect(() => {
    const v = videoRef.current;
    if (!v) return;
    v.muted = true;
    v.defaultMuted = true;

    let cancelled = false;

    const tryPlay = () => {
      if (cancelled) return;
      const p = v.play();
      if (p && p.catch) p.catch(() => {});
    };

    if (isActive) {
      if (v.getAttribute('src') !== c.video) {
        v.setAttribute('src', c.video);
        v.load();
      }
      // Attempt immediately AND once the browser has buffered enough.
      // Production browsers (notably Safari) reject a play() issued before
      // the freshly-loaded source is ready, which previously left the
      // 2nd/3rd portraits frozen on their poster. Retrying on canplay
      // guarantees each portrait starts once its data arrives.
      tryPlay();
      v.addEventListener('loadeddata', tryPlay);
      v.addEventListener('canplay', tryPlay);
      return () => {
        cancelled = true;
        v.removeEventListener('loadeddata', tryPlay);
        v.removeEventListener('canplay', tryPlay);
      };
    } else {
      try { v.pause(); } catch (e) {}
      if (v.getAttribute('src')) {
        v.removeAttribute('src');
        v.load();
      }
    }
  }, [isActive, c.video]);

  return (
    <button
      type="button"
      className={`prologue-char ${isActive ? 'is-active' : ''}`}
      style={{ '--accent': c.accent }}
      onClick={() => onActivate(index)}
      aria-pressed={isActive}
      aria-label={`${c.name} のプロフィールを表示`}>
      <div className="prologue-char-frame">
        <div className="prologue-char-corner prologue-char-corner-tl" aria-hidden="true"></div>
        <div className="prologue-char-corner prologue-char-corner-tr" aria-hidden="true"></div>
        <div className="prologue-char-corner prologue-char-corner-bl" aria-hidden="true"></div>
        <div className="prologue-char-corner prologue-char-corner-br" aria-hidden="true"></div>

        <div className="prologue-char-video-wrap">
          <video
            ref={videoRef}
            className="prologue-char-video"
            poster={c.poster}
            muted
            loop
            playsInline
            preload="none" />
          <div className="prologue-char-scan" aria-hidden="true"></div>
          <div className="prologue-char-vignette" aria-hidden="true"></div>
        </div>

        <div className="prologue-char-status">{c.age}</div>
      </div>

      <div className="prologue-char-plate">
        <div className="prologue-char-role">{c.role}</div>
        <div className="prologue-char-name">
          <span className="prologue-char-class">{c.classJa}</span>
          <span className="prologue-char-given">{c.name}</span>
          <span className="prologue-char-yomi">（{c.yomi}）</span>
        </div>
        <p className="prologue-char-blurb">
          {c.blurb.split('\n').map((line, i) =>
          <React.Fragment key={i}>
              {line}
              {i < c.blurb.split('\n').length - 1 ? <br /> : null}
            </React.Fragment>
          )}
        </p>
        <div className="prologue-char-emblems">
          <span className="prologue-char-emblems-label">SHIELD EMBLEM</span>
          <span className="prologue-char-emblems-row">
            {typeof c.emblems === 'number' ?
            Array.from({ length: c.emblems }).map((_, i) =>
            <img key={i} src="assets/shield-emblem.png?v=2" alt="" className="prologue-char-emblem-icon" />
            ) :
            <img src="assets/shield-emblem.png?v=2" alt="" className="prologue-char-emblem-icon prologue-char-emblem-unknown" />
            }
            <span className="prologue-char-emblems-count">
              ×{c.emblems}
            </span>
          </span>
        </div>
      </div>
    </button>);

}

function Prologue() {
  const [active, setActive] = React.useState(0);
  const [paused, setPaused] = React.useState(false);
  const [synopsisOpen, setSynopsisOpen] = React.useState(false);
  const activeRef = React.useRef(0);
  React.useEffect(() => {activeRef.current = active;}, [active]);

  // Auto-advance every 10 seconds (per spec).
  React.useEffect(() => {
    if (paused) return;
    const id = setInterval(() => {
      setActive((i) => (i + 1) % PROLOGUE_CHARS.length);
    }, 10000);
    return () => clearInterval(id);
  }, [paused]);

  // Brief manual-pause when user clicks a card.
  const suspendTimer = React.useRef(0);
  const onActivate = (i) => {
    setActive(i);
    setPaused(true);
    clearTimeout(suspendTimer.current);
    suspendTimer.current = setTimeout(() => setPaused(false), 12000);
  };
  React.useEffect(() => () => clearTimeout(suspendTimer.current), []);

  return (
    <section className="prologue" id="prologue">
      <div className="prologue-bg" aria-hidden="true"></div>
      <div className="prologue-halftone" aria-hidden="true"></div>
      <div className="prologue-scanlines" aria-hidden="true"></div>

      <div className="container" style={{ position: 'relative', zIndex: 2 }}>
        <div className="prologue-header">
          <div className="prologue-meta">
            <span className="prologue-meta-tag">◤ PROLOGUE</span>
            <span className="prologue-meta-sep">|</span>
            <span className="prologue-meta-id">FILE-2048 / NABI ARCHIVE</span>
          </div>
          <h2 className="prologue-title">
            <span className="prologue-title-sub">2048年、灼熱化した日本——。生物多様性を守る戦いが始まる。</span>
            <span className="prologue-title-main">絶滅の危機に立ち向かう、<br />最後の戦いへ。</span>
          </h2>
        </div>

        <div className="prologue-cast-wrap"
        onMouseEnter={() => setPaused(true)}
        onMouseLeave={() => setPaused(false)}>
          <div className="prologue-cast-label">
            <span>MAIN CHARACTER</span>
            <span className="prologue-cast-label-counter">
              <span className="prologue-cast-label-cur">{String(active + 1).padStart(2, '0')}</span>
              <span>/</span>
              <span>{String(PROLOGUE_CHARS.length).padStart(2, '0')}</span>
            </span>
          </div>

          <div className="prologue-cast" data-active={active}>
            {PROLOGUE_CHARS.map((c, i) =>
            <PrologueCharCard
              key={c.id}
              c={c}
              index={i}
              isActive={i === active}
              onActivate={onActivate} />

            )}
          </div>

          <div className="prologue-progress" aria-hidden="true">
            {PROLOGUE_CHARS.map((c, i) =>
            <div
              key={c.id}
              className={`prologue-progress-bar ${i === active ? 'is-active' : ''} ${i < active ? 'is-done' : ''}`}>
                <div
                className="prologue-progress-fill"
                style={{ animationPlayState: paused ? 'paused' : 'running' }} />
              
              </div>
            )}
          </div>
          <div className="prologue-progress-hint">
            10秒ごとに自動で次のキャラクターへ ・ クリックで切替
          </div>
        </div>

        <div className="prologue-synopsis-wrap">
          <div className="prologue-synopsis-label">
            <span className="prologue-synopsis-label-mono">STORY</span>
            <span className="prologue-synopsis-label-ja">あらすじ</span>
            <button
              type="button"
              className="prologue-synopsis-toggle"
              aria-expanded={synopsisOpen}
              onClick={() => setSynopsisOpen((v) => !v)}>
              {synopsisOpen ? '閉じる ▲' : '全文を読む ▼'}
            </button>
          </div>

          <div className={`prologue-synopsis-body ${synopsisOpen ? 'is-open' : 'is-collapsed'}`}>
            <div className="prologue-synopsis">
              <div className="prologue-synopsis-col">
                {PROLOGUE_SYNOPSIS.slice(0, 3).map((p, i) =>
                <p key={i} className={`prologue-synopsis-p ${i === 0 ? 'prologue-synopsis-lead' : ''}`}>{p}</p>
                )}
              </div>
              <div className="prologue-synopsis-col">
                {PROLOGUE_SYNOPSIS.slice(3).map((p, i) =>
                <p key={i} className="prologue-synopsis-p">{p}</p>
                )}
              </div>
            </div>
            <div className="prologue-gear">
              <div className="prologue-gear-head">
                <span className="prologue-gear-mono">KEY ITEM</span>
                <span className="prologue-gear-ja">物語を支える、重要なグッズ</span>
              </div>
              <figure className="prologue-gear-figure">
                <img
                  src="assets/genome-lens.png"
                  alt="ゲノムレンズ — 生き物や植物をスキャンして、その遺伝情報をカードに変換するデバイス"
                  className="prologue-gear-img" />
              </figure>
            </div>
            {!synopsisOpen ? <div className="prologue-synopsis-fade" aria-hidden="true"></div> : null}
          </div>

          {!synopsisOpen ?
          <button
            type="button"
            className="prologue-synopsis-more"
            onClick={() => setSynopsisOpen(true)}>
            続きを読む ▼
          </button> :
          null}

        </div>
      </div>
    </section>);

}

function PrologueDisclaimer() {
  return (
    <section className="prologue-disclaimer-section" aria-label="フィクション注意書き">
      <div className="container">
        <div className="prologue-disclaimer">
          <div className="prologue-disclaimer-tag">FICTION / 注意書き</div>
          <p>
            ※ 物語・キャラクターはフィクションです。実在の人物・団体・国家機関・出来事・地名などとは一切関係ありません。
          </p>
        </div>
      </div>
    </section>);

}

Object.assign(window, { Prologue, PrologueCharCard, PrologueDisclaimer });