/* jrec-view.jsx — 「記録」タブ（/demo のみ表示）。JARA主催大会 2000-2025 の最速記録。
   構成：全種目の一覧表（入口。濃さ＝世界一比）→ 行を押すと、その種目の「段ばしご」
   （世界→U23→日本→大学生→新人戦 の5段。各行に最速からの距離の帯）＋大会別・会場別。
   出典：日本ローイング協会 公式大会結果アーカイブ（非公式利用）。参考記録。 */

// 並びは「無差別のすぐ後ろに同じ艇種の軽量級」（M1X→LM1X→M2X→…＝本人指示）
const JREC_M_ALL = ["M1X","LM1X","M2X","LM2X","M2-","LM2-","M4X","LM4X","M4-","LM4-","M4+","M8+","LM8+","M2+"];
const JREC_W_ALL = ["W1X","LW1X","W2X","LW2X","W2-","LW2-","W4X","LW4X","W4+","W8+","W4X+","LW4X+"];
const JREC_L = ["LM1X","LM2X","LM2-","LM4X","LM4-","LM8+","LW1X","LW2X","LW2-","LW4X","LW4X+"];
const JREC_OPEN = JREC_M_ALL.concat(JREC_W_ALL).filter((x) => x[0] !== "L");   // 無差別（オープン）だけ
const JREC_GROUPS = {
  all:  { label: "全種目", evs: JREC_M_ALL.concat(JREC_W_ALL) },
  m:    { label: "男子", evs: JREC_M_ALL },
  w:    { label: "女子", evs: JREC_W_ALL },
  open: { label: "オープン", evs: JREC_OPEN },
  l:    { label: "軽量級", evs: JREC_L },
};
const jrecGender = (ev) => (/^L?W/.test(ev) ? "w" : "m");
const JREC_EVNAME = { "M1X":"男子シングルスカル","M2X":"男子ダブルスカル","M2-":"男子ペア",
  "M4X":"男子クォドルプル","M4-":"男子フォア","M4+":"男子舵手つきフォア","M8+":"男子エイト",
  "M2+":"男子舵手つきペア","W1X":"女子シングルスカル","W2X":"女子ダブルスカル","W2-":"女子ペア",
  "W4X":"女子クォドルプル","W4+":"女子舵手つきフォア","W8+":"女子エイト",
  "W4X+":"女子舵手つきクォドルプル" };
const jrecName = (ev) => JREC_EVNAME[ev] || (ev[0] === "L" ? "軽量級 " + (JREC_EVNAME[ev.slice(1)] || ev.slice(1)) : ev);
const jrecSec = (t) => { const m = String(t || "").match(/^(\d+):(\d+(?:\.\d+)?)$/); return m ? +m[1] * 60 + parseFloat(m[2]) : null; };

function JrecView() {
  const J = window.KANSAI.JREC;
  if (!J) return null;
  const [mode, setMode] = React.useState("ev");      // ev=種目別 team=大学別
  const [grp, setGrp] = React.useState("all");
  const [view, setView] = React.useState("byev");    // byev=種目ごと(H・既定) / mix=全記録速い順(H2)
  const [ev, setEv] = React.useState(null);          // 詳細を開いている種目
  const [selKey, setSelKey] = React.useState(null);  // 開いている行（種目|区分）
  const [team, setTeam] = React.useState(null);
  const [q, setQ] = React.useState("");
  const M = J.meta.meets;
  const IC = window.KANSAI.RECORDS || {};
  const U23 = Object.assign({}, window.KANSAI.U23 || {}, window.KANSAI.U23_L || {});
  const U23_NONE = window.KANSAI.U23_NONE || {};
  const WBT = Object.assign({}, window.KANSAI.WBT || {}, window.KANSAI.WBT_L || {});

  // ある種目の5段（速い順）。無い段は抜ける
  const tiers = (x) => {
    const e = J.ev[x] || {};
    const W = WBT[x], U = U23[x], I = IC[x];
    const rows = [];
    const jj = (a) => a.filter(Boolean).join("・");
    if (W) rows.push({ key: "wbt", lb: "世界最速", t: W.t, who: W.crew, sub: W.year + "・" + (W.venue || ""), cls: "wbt",
      det: { who: W.crew, when: W.year + "年", where: jj([W.venue]) } });
    if (U && U.t) rows.push({ key: "u23", lb: "U23世界最速", t: U.t, who: U.crew, sub: U.year + "・" + (U.venue || ""), cls: "u23",
      det: { who: U.crew, when: U.year + "年", where: jj(["U23世界選手権", U.venue]),
             note: U.last ? "この種目は" + U.last + "年で廃止。記録は更新されません" : null } });
    if (e.japan) rows.push({ key: "jp", lb: "日本最速", t: e.japan.t, who: e.japan.o, sub: e.japan.y + "・" + (M[e.japan.m] || e.japan.m), cls: "jp",
      det: { who: e.japan.o, when: e.japan.y + "年", where: jj([M[e.japan.m] || e.japan.m, e.japan.r, e.japan.v]) } });
    if (e.univ) rows.push({ key: "univ", lb: "大学生 日本最速", t: e.univ.t, who: e.univ.o, sub: e.univ.y + "・" + (M[e.univ.m] || e.univ.m), cls: "univ",
      det: { who: e.univ.o, when: e.univ.y + "年", where: jj([M[e.univ.m] || e.univ.m, e.univ.r, e.univ.v]) } });
    if (I) rows.push({ key: "ic", lb: "新人戦最速", t: I.t, who: I.crew, sub: I.year + "・" + I.round, cls: "ic",
      det: { who: I.crew, when: I.year + "年", where: jj(["全日本新人", I.round, "戸田"]) } });
    rows.forEach((r) => { r.sec = jrecSec(r.t); });
    return rows.filter((r) => r.sec != null).sort((a, b) => a.sec - b.sec);
  };

  const SHORT = { wbt: "世界", u23: "U23", jp: "日本", univ: "大学生", ic: "新人戦" };
  const FLAG = { wbt: "\u{1F30E}", u23: "\u{1F30E}", jp: "\u{1F1EF}\u{1F1F5}", univ: "\u{1F1EF}\u{1F1F5}", ic: "\u{1F1EF}\u{1F1F5}" };
  // 軸は「いま表示している範囲の全記録」から決める。H/H2で同じ物差しになるよう共通化。
  const scaleOf = (recs) => {
    const A0 = Math.floor(recs[0].sec / 60) * 60, A1 = Math.ceil(recs[recs.length - 1].sec / 60) * 60;
    const ticks = []; for (let t = A0; t <= A1; t += 60) ticks.push(t);
    return { A0, A1, ticks, Wp: (sec) => Math.max(0, Math.min(100, (sec - A0) / (A1 - A0) * 100)) };
  };
  const allRecs = () => {
    const evs = JREC_GROUPS[grp].evs.filter((x) => J.ev[x] || IC[x]);
    const recs = [];
    evs.forEach((x) => tiers(x).forEach((r) => recs.push(Object.assign({ ev: x, g: jrecGender(x) }, r))));
    return recs;
  };
  const axisBar = (S) => (
    <div className="jrs-axis">
      <span className="jrs-axis-pad" />
      <span className="jrs-axis-track">
        {S.ticks.map((t) => <b className="num" key={t} style={{ left: S.Wp(t) + "%" }}>{Math.floor(t / 60)}:00</b>)}
      </span>
      <span className="jrs-axis-t" />
    </div>
  );
  const legend = () => (
    <div className="jrs-legend">
      {[["wbt", "世界"], ["u23", "U23"], ["jp", "日本"], ["univ", "大学生"], ["ic", "新人戦"]].map(([k, lb]) => (
        <span key={k}><i className={"jrs-sw " + k} /><span className="jrs-flag">{FLAG[k]}</span>{lb}</span>
      ))}
      <span className="jrs-lghint"><span className="jrs-flag">{"\u{1F30E}"}</span>＝世界の記録　<span className="jrs-flag">{"\u{1F1EF}\u{1F1F5}"}</span>＝日本の記録</span>
    </div>
  );

  // ── 案H：種目ごとに5本ずつ（種目の並びは固定） ────────────────
  const byEventList = () => {
    const recs = allRecs();
    if (!recs.length) return null;
    const S = scaleOf(recs.slice().sort((a, b) => a.sec - b.sec));
    const evs = JREC_GROUPS[grp].evs.filter((x) => J.ev[x] || IC[x]);
    return (<>
      {legend()}
      {axisBar(S)}
      <div className="jrs jrb">
        {evs.map((x) => {
          const T = tiers(x), g = jrecGender(x), open = ev === x;
          const none = U23_NONE[x];
          return (
            <div className={"jrb-blk g" + g + (open ? " open" : "")} key={x}>
              <button type="button" className="jrb-hd" onClick={() => { setEv(open ? null : x); setSelKey(null); }}>
                <span className={"jrb-ev" + (x[0] === "L" ? " lw" : "")}>{x}</span>
                <span className="jrb-nm">{jrecName(x)}</span>
                <span className="jrb-x">{open ? "閉じる" : "詳細"}</span>
              </button>
              {T.map((r) => {
                const rk = x + "|" + r.key, ropen = selKey === rk;
                return (
                  <React.Fragment key={r.key}>
                    <button type="button" className={"jrb-row" + (ropen ? " on" : "")}
                            onClick={() => setSelKey(ropen ? null : rk)}>
                      <span className={"jrb-lb " + r.key}><span className="jrs-flag">{FLAG[r.key]}</span>{SHORT[r.key]}</span>
                      <span className="jrs-track">
                        {S.ticks.map((t) => <i className="jrs-grid" key={t} style={{ left: S.Wp(t) + "%" }} />)}
                        <span className={"jrs-bar " + r.key} style={{ width: S.Wp(r.sec) + "%" }} />
                      </span>
                      <b className="jrs-t num">{r.t}</b>
                    </button>
                    {ropen && r.det && (
                      <div className="jrb-det">
                        <b>{r.det.who}</b>　{r.det.when}・{r.det.where}
                        {r.det.note && <span className="jrb-det-note">{r.det.note}</span>}
                      </div>
                    )}
                  </React.Fragment>
                );
              })}
              {none && <div className="jrb-none">U23：{none}</div>}
              {open && <div className="jrs-detail">{ladder()}</div>}
            </div>
          );
        })}
      </div>
      <p className="sizenote" style={{ margin: "6px 2px 0" }}>
        横軸は {Math.floor(S.A0 / 60)}:00〜{Math.floor(S.A1 / 60)}:00 の実タイム。種目をまたいで同じ物差しなので、
        バーの長さをそのまま比べられます。<b>バーを押すと、いつ・どこで・どのクルーが出した記録かが開きます</b>。
        種目名の「詳細」で大会別・会場別の記録へ。
      </p>
    </>);
  };

  // ── 案H2：全記録を速い順に。種目も区分も混ぜる ────────────────
  const sortedList = () => {
    const recs = allRecs().sort((a, b) => a.sec - b.sec || a.ev.localeCompare(b.ev));
    if (!recs.length) return null;
    const S = scaleOf(recs), { A0, A1, ticks, Wp } = S;
    const openRow = (r) => {
      const k = r.ev + "|" + r.key;
      if (selKey === k) { setSelKey(null); setEv(null); } else { setSelKey(k); setEv(r.ev); }
    };
    return (<>
      {legend()}
      {axisBar(S)}
      <div className="jrs">
        {recs.map((r, i) => {
          const k = r.ev + "|" + r.key, open = selKey === k, same = ev === r.ev;
          return (
            <React.Fragment key={k}>
              <button type="button" className={"jrs-row g" + r.g + (same ? " same" : "") + (open ? " open" : "")} onClick={() => openRow(r)}>
                <span className="jrs-rk num">{i + 1}</span>
                <span className="jrs-ev">{r.ev}</span>
                <span className={"jrs-tier " + r.key}><span className="jrs-flag">{FLAG[r.key]}</span>{SHORT[r.key]}</span>
                <span className="jrs-track">
                  {ticks.map((t) => <i className="jrs-grid" key={t} style={{ left: Wp(t) + "%" }} />)}
                  <span className={"jrs-bar " + r.key} style={{ width: Wp(r.sec) + "%" }} />
                </span>
                <b className="jrs-t num">{r.t}</b>
              </button>
              {open && (
                <div className="jrs-detail">
                  {r.det && <div className="jrb-det top"><b>{r.det.who}</b>　{r.det.when}・{r.det.where}
                    {r.det.note && <span className="jrb-det-note">{r.det.note}</span>}</div>}
                  {ladder()}
                </div>
              )}
            </React.Fragment>
          );
        })}
      </div>
      <p className="sizenote" style={{ margin: "6px 2px 0" }}>
        横軸は {Math.floor(A0 / 60)}:00〜{Math.floor(A1 / 60)}:00 の実タイム。種目も区分も混ぜて、速い順に並べています。
        行を押すと、その種目の記録（5段・大会別・会場別）が開き、同じ種目の行に色が付きます。
      </p>
    </>);
  };

  // ── 段ばしご（選んだ種目の詳細） ─────────────────────────────
  const ladder = () => {
    const e = J.ev[ev] || {};
    const T = tiers(ev);
    if (!T.length) return null;
    const base = T[0].sec, span = Math.max(0.01, T[T.length - 1].sec - base);
    const meets = Object.entries(e.meet || {}).sort((a, b) => jrecSec(a[1].t) - jrecSec(b[1].t));
    const venues = Object.entries(e.venue || {}).sort((a, b) => jrecSec(a[1].t) - jrecSec(b[1].t));
    return (
      <div>
        <div className="subhead" style={{ marginTop: 4 }}><IconTrophy className="ic" size={16} />{jrecName(ev)}
          <span className="shsub">{T[0].lb}からの距離{e.n ? " · " + e.n.toLocaleString() + "レースから" : ""}</span></div>
        <div className="recbox jrd">
          {T.map((r, i) => {
            const gap = r.sec - base, w = gap / span * 100;
            return (
              <div className={"jrd-row " + r.cls} key={r.key}>
                <div className="jrd-top">
                  <span className="rec-lb"><span className="jrs-flag">{FLAG[r.key]}</span>{r.lb}</span>
                  <b className="rec-t">{r.t}</b>
                  <span className="rec-who">{r.who}</span>
                  <span className="rec-yr">{r.sub}</span>
                </div>
                <div className="jrd-bar">
                  <span className="jrd-track">
                    {i === 0 ? <span className="jrd-origin" /> : <span className={"jrd-fill " + r.cls} style={{ width: w + "%" }} />}
                  </span>
                  <span className={"jrd-gap" + (r.cls === "ic" ? " hot" : "")}>{i === 0 ? "基準" : "＋" + gap.toFixed(2) + "秒"}</span>
                </div>
              </div>
            );
          })}
        </div>
        {meets.length > 0 && (<>
          <div className="subhead" style={{ marginTop: 16 }}>大会別の最速</div>
          <div className="jrl">
            {meets.map(([k, r]) => (
              <div className={"jrl-row" + (k === "freshman" ? " ic" : "")} key={k}>
                <span className="jrl-m">{M[k] || k}</span><b className="jrl-t">{r.t}</b>
                <span className="jrl-o">{r.o}</span><span className="jrl-y">{r.y}年 {r.r}</span>
              </div>
            ))}
          </div>
        </>)}
        {(U23_NONE[ev] || !U23[ev]) && (
          <p className="rec-none">U23世界最速：{U23_NONE[ev] || "記録を確認できていません"}</p>
        )}
        {U23[ev] && U23[ev].last && (
          <p className="rec-none">この種目は{U23[ev].last}年を最後にU23世界選手権で行われていないため、U23の記録は今後更新されません。</p>
        )}
        {venues.length > 0 && (<>
          <div className="subhead" style={{ marginTop: 16 }}>会場別の最速<span className="shsub">コースレコード</span></div>
          <div className="jrl">
            {venues.map(([k, r]) => (
              <div className="jrl-row" key={k}>
                <span className="jrl-m">{k}</span><b className="jrl-t">{r.t}</b>
                <span className="jrl-o">{r.o}</span><span className="jrl-y">{r.y}年 {M[r.m] || r.m}</span>
              </div>
            ))}
          </div>
        </>)}
      </div>
    );
  };

  // ── 大学別 ──────────────────────────────────────────────
  const teamView = () => {
    const ALL = JREC_M_ALL.concat(JREC_W_ALL);
    if (team) {
      const t = J.teams[team] || {};
      const total = ALL.filter((x) => t[x]).length;
      const stars = ALL.filter((x) => {
        const j = J.ev[x]; return t[x] && j && j.univ && Math.abs(jrecSec(t[x].t) - jrecSec(j.univ.t)) < 0.001;
      }).length;
      const GROUPS = [["m", "男子", JREC_M_ALL], ["w", "女子", JREC_W_ALL]];
      return (<>
        <button className="jr-back" onClick={() => setTeam(null)}>← 大学一覧へ</button>
        <div className="subhead"><IconTrophy className="ic" size={16} />{team}
          <span className="shsub">{total}種目{stars > 0 ? "・★" + stars : ""}</span></div>
        <p className="sizenote" style={{ margin: "0 2px 8px" }}>
          2000〜2025年のJARA主催大会で、この大学が出したいちばん速いタイム。
          <b>＋◯秒は、その種目の「大学生 日本最速」との差</b>です。★はこの大学が持っています。
        </p>
        {GROUPS.map(([g, label, evsAll]) => {
          const evs = evsAll.filter((x) => t[x]);
          if (!evs.length) return null;
          return (
            <React.Fragment key={g}>
              <div className={"jru-hd g" + g}>{label}<span className="jru-hdn">{evs.length}種目</span></div>
              <div className="jrl jru">
                {evs.map((x) => {
                  const r = t[x], j = J.ev[x];
                  const best = j && j.univ ? jrecSec(j.univ.t) : null;
                  const d = best != null ? jrecSec(r.t) - best : null;
                  const top = d != null && d < 0.001;
                  const rg = jrecGender(x);
                  return (
                    <div className={"jru-row g" + rg + (x[0] === "L" ? " lw" : "") + (top ? " best" : "")} key={x}>
                      <span className="jru-ev">{x}</span>
                      <b className="jru-t num">{r.t}</b>
                      {top ? <span className="jru-star">★ 大学生 日本最速</span>
                           : (d != null && <span className="jru-gap">＋{d.toFixed(1)}秒</span>)}
                      <span className="jru-sub">{r.y}年・{M[r.m] || r.m} {r.r}</span>
                    </div>
                  );
                })}
              </div>
            </React.Fragment>
          );
        })}
      </>);
    }
    const names = Object.keys(J.teams).filter((n) => !q || n.indexOf(q) >= 0)
      .sort((a, b) => Object.keys(J.teams[b]).length - Object.keys(J.teams[a]).length || a.localeCompare(b, "ja"));
    return (<>
      <div className="subhead"><IconTeams className="ic" size={16} />大学別の最速記録<span className="shsub">{J.meta.teams}校</span></div>
      <input className="jr-q" value={q} onChange={(e) => setQ(e.target.value)} placeholder="大学名で絞り込み" />
      <div className="jrt">
        {names.map((n) => (
          <button className="jrt-b" key={n} onClick={() => setTeam(n)}>
            <span className="jrt-n">{n}</span><span className="jrt-c">{Object.keys(J.teams[n]).length}種目</span>
          </button>
        ))}
      </div>
    </>);
  };

  return (
    <div className="view">
      <div className="chips jr-mode">
        <button className={"chip" + (mode === "ev" ? " on" : "")} onClick={() => { setMode("ev"); setTeam(null); }}>種目別</button>
        <button className={"chip" + (mode === "team" ? " on" : "")} onClick={() => setMode("team")}>大学別</button>
      </div>
      {mode === "ev" ? (<>
        <div className="subhead" style={{ marginTop: 4 }}><IconChart className="ic" size={16} />
          {view === "mix" ? "全記録 速い順" : "種目ごとの最速"}
          <span className="shsub">バーの長さ＝タイム · 短いほど速い</span></div>
        <div className="mtoggle jrv">
          <button type="button" className={view === "byev" ? "on" : ""} onClick={() => { setView("byev"); setEv(null); setSelKey(null); }}>種目ごと</button>
          <button type="button" className={view === "mix" ? "on" : ""} onClick={() => { setView("mix"); setEv(null); setSelKey(null); }}>速い順</button>
        </div>
        <div className="chips">
          {Object.entries(JREC_GROUPS).map(([k, g]) => (
            <button className={"chip" + (grp === k ? " on" : "")} key={k} onClick={() => { setGrp(k); setEv(null); setSelKey(null); }}>{g.label}</button>
          ))}
        </div>
        {view === "mix" ? sortedList() : byEventList()}
      </>) : teamView()}
      <p className="sizenote" style={{ margin: "14px 2px 0" }}>
        日本ローイング協会の公式アーカイブから、全日本選手権・インカレ・オックスフォード盾・ジャパンオープン・
        全日本新人・全日本社会人・全日本軽量級の{J.meta.years[0]}〜{J.meta.years[1]}年、
        <b>{J.meta.rows.toLocaleString()}レース</b>を集計しました。
        <br />予選から決勝まで全ラウンドのタイムが対象です。風で大きく変わるため<b>参考記録</b>で、
        JARAが認定した記録ではありません。年齢別・B級（1000m）・ナックルフォア・パラ・ジュニアの各種目は
        除いています。大学には大学混成・大学院・高専を含み、OB艇は含みません。
      </p>
    </div>
  );
}
