/* app.jsx — WC3 2026 観戦UI（放送グラフィック風・日本代表メイン）
   データ: /api/wc3.json（本番Worker）→ ./wc3.json（ローカル）
   日本代表クルー: JARA強化委員会 発第2025-365号 */
const { useState, useEffect } = React;

const EVMAP = {
  "Men's Single Sculls": ["男子シングルスカル", "M1x"], "Women's Single Sculls": ["女子シングルスカル", "W1x"],
  "Men's Double Sculls": ["男子ダブルスカル", "M2x"], "Women's Double Sculls": ["女子ダブルスカル", "W2x"],
  "Men's Quadruple Sculls": ["男子クォドルプル", "M4x"], "Women's Quadruple Sculls": ["女子クォドルプル", "W4x"],
  "Men's Pair": ["男子ペア", "M2-"], "Women's Pair": ["女子ペア", "W2-"],
  "Men's Four": ["男子フォア", "M4-"], "Women's Four": ["女子フォア", "W4-"],
  "Men's Eight": ["男子エイト", "M8+"], "Women's Eight": ["女子エイト", "W8+"],
  "Lightweight Men's Single Sculls": ["軽量級男子シングル", "LM1x"], "Lightweight Women's Single Sculls": ["軽量級女子シングル", "LW1x"],
  "Lightweight Men's Double Sculls": ["軽量級男子ダブル", "LM2x"], "Lightweight Women's Double Sculls": ["軽量級女子ダブル", "LW2x"],
  "Mixed Double Sculls": ["混合ダブルスカル", "Mix2x"],
  "PR1 Men's Single Sculls": ["PR1 男子シングル", "PR1 M1x"], "PR1 Women's Single Sculls": ["PR1 女子シングル", "PR1 W1x"],
  "PR2 Mixed Double Sculls": ["PR2 混合ダブル", "PR2 Mix2x"], "PR3 Mixed Double Sculls": ["PR3 混合ダブル", "PR3 Mix2x"],
  "PR3 Mixed Coxed Four": ["PR3 混合舵手付フォア", "PR3 Mix4+"], "PR3 Women's Pair": ["PR3 女子ペア", "PR3 W2-"],
};
const evJa = (n) => (EVMAP[n] ? EVMAP[n][0] : n);
const evAb = (n) => (EVMAP[n] ? EVMAP[n][1] : "");
const phaseJa = (n) => String(n || "")
  .replace(/Final A/i, "A決勝").replace(/Final B/i, "B決勝").replace(/Final C/i, "C決勝").replace(/Final D/i, "D決勝")
  .replace(/Final/i, "決勝").replace(/Semifinal/i, "準決勝").replace(/Quarterfinal/i, "準々決勝")
  .replace(/Repechage/i, "敗者復活").replace(/Heat/i, "予選");
const isFinalA = (n) => /Final A|A決勝|^Final$|決勝/.test(String(n || "")) && !/B|C|D/.test(String(n || ""));

// 日本代表 WC3 出場クルー（出典：JARA強化委員会 発第2025-365号）。priority=重点強化（通年フル代表）
const JP_WC3 = [
  { ev: "Men's Single Sculls", priority: true, crew: [["櫻間 達也", "NTT東日本"]] },
  { ev: "Women's Pair", priority: true, crew: [["髙野 晃帆", "関西電力"], ["米川 志保", "トヨタ自動車"]] },
  { ev: "Men's Double Sculls", crew: [["宮口 大誠", "NTT東日本"], ["武田 匡弘", "関西電力"]] },
  { ev: "Men's Four", crew: [["岸本 健吾", "NTT東日本"], ["津志田 匠太郎", "NTT東日本"], ["石政 雄也", "明治安田"], ["蛭川 暢之", "明治安田"]] },
  { ev: "Women's Four", crew: [["飯島 佐和子", "明治安田"], ["松田 京子", "明治安田"], ["岸本 唯佳", "NTT東日本"], ["鈴木 伶奈", "NTT東日本"]] },
  { ev: "Lightweight Women's Double Sculls", crew: [["米澤 知華", "明治安田"], ["冨田 千愛", "無所属"]] },
];
const jpByEvent = Object.fromEntries(JP_WC3.map((j) => [j.ev, j]));

function useCountdown(target) {
  const [now, setNow] = useState(() => Date.now());
  useEffect(() => { const id = setInterval(() => setNow(Date.now()), 1000); return () => clearInterval(id); }, []);
  const ms = Math.max(0, target - now);
  return { d: Math.floor(ms / 864e5), h: Math.floor((ms % 864e5) / 36e5), m: Math.floor((ms % 36e5) / 6e4), s: Math.floor((ms % 6e4) / 1e3), live: ms === 0 };
}

// ヒーローの水面アニメ：6艇が左→右に競漕、先頭は日本（赤）
function HeroWater() {
  const lanes = [
    { y: 2, w: 60, o: 0.22, d: 44, delay: -20, jp: false },
    { y: 12, w: 70, o: 0.3, d: 42.5, delay: -21, jp: false },
    { y: 22, w: 80, o: 0.4, d: 41, delay: -18.5, jp: false },
    { y: 33, w: 92, o: 1, d: 39.5, delay: -19.5, jp: true },
    { y: 45, w: 104, o: 0.5, d: 41.5, delay: -20.5, jp: false },
    { y: 57, w: 116, o: 0.62, d: 43, delay: -19, jp: false },
  ];
  return (
    <div className="hw" aria-hidden="true">
      {lanes.map((b, i) => (
        <div className="hw-lane" key={i} style={{ "--y": b.y + "px", "--d": b.d + "s", "--delay": b.delay + "s" }}>
          <svg className={"hw-boat" + (b.jp ? " jp" : "")} viewBox="0 0 120 18" style={{ width: b.w + "px", opacity: b.o }}>
            <g stroke="currentColor" strokeWidth="1.1" strokeLinecap="round">
              <line x1="38" y1="9" x2="32" y2="3" /><line x1="54" y1="9" x2="60" y2="15" />
              <line x1="70" y1="9" x2="64" y2="3" /><line x1="86" y1="9" x2="92" y2="15" />
            </g>
            <path d="M8 9 C30 6.5 92 6.5 114 8.4 C115 8.7 115 9.3 114 9.6 C92 11.5 30 11.5 8 9 Z" fill="currentColor" />
          </svg>
        </div>
      ))}
    </div>
  );
}

function Hero({ comp, eventCount }) {
  const c = useCountdown(new Date("2026-06-26T09:00:00+02:00").getTime());
  return (
    <header className="hero">
      <span className="hero-sun" aria-hidden="true" />
      <span className="hero-grid" aria-hidden="true" />
      <HeroWater />
      <div className="hero-in">
        <div className="hero-top">
          <span className="badge-jp">🇯🇵 TEAM JAPAN</span>
          <span className="kick">World Rowing Cup III · 2026</span>
          <span className="unofficial">非公式 / UNOFFICIAL</span>
        </div>
        <h1 className="hero-en">WORLD<br />ROWING CUP <span>III</span></h1>
        <div className="hero-jp">ワールドカップ第3戦</div>
        <div className="hero-meta">
          <span>🇨🇭 ルツェルン（スイス）</span><span className="dot">·</span><span>6.26 – 6.28</span>
        </div>
        <div className="cd">
          <div className="cd-l">{c.live ? "● RACING NOW" : "COUNTDOWN TO START"}</div>
          <div className="cd-nums">
            {[[c.d, "DAYS"], [c.h, "HRS"], [c.m, "MIN"], [c.s, "SEC"]].map(([v, l], i) => (
              <React.Fragment key={l}>
                {i > 0 && <span className="cd-sep">:</span>}
                <div className={"cd-u" + (l === "SEC" ? " sec" : "")}><b key={v}>{String(v).padStart(2, "0")}</b><span>{l}</span></div>
              </React.Fragment>
            ))}
          </div>
        </div>
        <div className="hero-stats">
          <div className="hs"><b>{eventCount || "—"}</b><span>EVENTS</span></div>
          <div className="hs jp"><b>6</b><span>日本艇</span></div>
          <div className="hs"><b>3</b><span>DAYS</span></div>
        </div>
      </div>
    </header>
  );
}

function TeamJapan() {
  return (
    <section className="tj">
      <div className="tj-head">
        <span className="tj-bar" />
        <div>
          <div className="tj-en">TEAM JAPAN</div>
          <h2>日本代表 出場クルー</h2>
        </div>
        <span className="tj-count">{JP_WC3.length}<i>艇</i></span>
      </div>
      <div className="tj-grid">
        {JP_WC3.map((b, i) => (
          <article className={"tj-card" + (b.priority ? " pri" : "")} key={i}>
            <div className="tj-c-top">
              <span className="tj-ab">{evAb(b.ev)}</span>
              {b.priority && <span className="tj-star">★ 重点強化</span>}
            </div>
            <div className="tj-ev">{evJa(b.ev)}</div>
            <div className="tj-mem">
              {b.crew.map((m, j) => (<div className="tj-m" key={j}><b>{m[0]}</b><i>{m[1]}</i></div>))}
            </div>
          </article>
        ))}
      </div>
      <div className="src-note">日本代表クルー出典：JARA強化委員会 発第2025-365号</div>
    </section>
  );
}

function Boat({ b, final }) {
  const medal = final && b.rank >= 1 && b.rank <= 3 ? ["", "gold", "silver", "bronze"][b.rank] : "";
  return (
    <div className={"boat" + (b.isJpn ? " jpn" : "") + (medal ? " " + medal : "")}>
      <span className="b-rank">{b.rank || "–"}</span>
      <span className="b-cty">{b.countryCode || "—"}</span>
      <span className="b-main"><b>{b.country || b.label}</b></span>
      <span className="b-time">{b.time ? b.time.replace(/^0:/, "").replace(/^00:/, "") : (b.remark || "")}</span>
    </div>
  );
}

function EventRow({ ev }) {
  const [open, setOpen] = useState(false);
  const has = ev.races && ev.races.length > 0;
  const jp = jpByEvent[ev.name];
  return (
    <div className={"ev" + (has ? " has" : "") + (jp ? " jp" : "")}>
      <div className="ev-h" onClick={has ? () => setOpen(!open) : undefined}>
        <span className="ev-ab">{evAb(ev.name)}</span>
        <span className="ev-nm">{evJa(ev.name)}{jp && <span className="ev-jp">🇯🇵</span>}</span>
        <span className="ev-st">{has ? (open ? "▲" : "結果 ▼") : "発表前"}</span>
      </div>
      {open && has && (
        <div className="ev-body">
          {ev.races.map((r) => {
            const fin = isFinalA(r.name);
            return (
              <div className={"race" + (fin ? " final" : "")} key={r.id}>
                <div className="race-h">{fin && <span className="fin-tag">FINAL</span>}{phaseJa(r.name).replace(evJa(ev.name), "").replace(ev.name, "").trim() || "レース"}</div>
                {r.boats.length ? r.boats.map((b, i) => <Boat b={b} final={fin} key={i} />) : <div className="race-empty">エントリー発表前</div>}
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

function App() {
  const [data, setData] = useState(null);
  const [err, setErr] = useState(null);
  useEffect(() => {
    (async () => {
      for (const u of ["/api/wc3.json", "./wc3.json"]) {
        try { const r = await fetch(u, { cache: "no-store" }); if (r.ok) { setData(await r.json()); return; } } catch {}
      }
      setErr("データを読み込めませんでした");
    })();
  }, []);
  const races = data ? data.counts.races : 0;
  return (
    <div className="app">
      <Hero comp={data && data.competition} eventCount={data && data.events.length} />
      <main className="wrap">
        <div className={"notice" + (races > 0 ? " live" : "")}>
          {races > 0
            ? <span><b className="liveb"><i className="ld" />LIVE</b> World Rowing公式から結果を自動更新中</span>
            : <span><b>組分け・結果は発表後に自動反映</b> · 現在はエントリー種目一覧</span>}
          {data && <i>更新 {new Date(data.fetchedAt).toLocaleString("ja-JP", { month: "numeric", day: "numeric", hour: "2-digit", minute: "2-digit" })}</i>}
        </div>

        <TeamJapan />

        <section className="sec">
          <div className="sec-head"><span className="sec-bar" /><h2>全種目</h2><span className="sec-count">{data ? data.events.length : "—"}</span></div>
          {err && <div className="err">{err}</div>}
          {!data && !err && <div className="loading">読み込み中…</div>}
          {data && <div className="ev-list">{data.events.map((ev) => <EventRow ev={ev} key={ev.id} />)}</div>}
        </section>

        <footer className="ft">
          {data && <div className="ft-comp">{data.competition.name}</div>}
          <div className="ft-note">⚠ 非公式ファンサイトです。JARA・World Rowing 公認／提供ではありません。</div>
          <div className="ft-src">DATA · <a href="https://worldrowing.com" target="_blank" rel="noopener">World Rowing 公式</a></div>
        </footer>
      </main>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
