/* teams.jsx — 学校一覧（地方ブロック別）・検索・お気に入り・学校詳細
   ─────────────────────────────────────────────────────────────
   ・部門は「全国選抜」1つだけなので、部門フィルタは置かない。
     代わりに window.KANSAI.PREF（学校名→都道府県）を使った【地方ブロックの絞り込み】を置く。
   ・高校（未成年）の大会なので、名簿・カナ・学年・写真・選手検索は扱わない。
     シングルスカルの氏名だけは公式結果に出ているため、engine の isMinorTeam
     （config.js の showAthleteNames）が許すときだけ出す。
   ・日程マスは「予定の発艇時間帯」と、公式結果が出た枠の「実際の発艇時刻・組・レーン」で作る。 */

/* ── 都道府県 → 地方ブロック ─────────────────────────────
   全国大会なので47都道府県すべてを並べておく（出場が無い県は表に出ない）。 */
const REGIONS = [
  { key: "tohoku", label: "北海道・東北", prefs: ["北海道", "青森", "岩手", "宮城", "秋田", "山形", "福島"] },
  { key: "kanto", label: "関東", prefs: ["茨城", "栃木", "群馬", "埼玉", "千葉", "東京", "神奈川"] },
  { key: "chubu", label: "中部", prefs: ["新潟", "富山", "石川", "福井", "山梨", "長野", "岐阜", "静岡", "愛知"] },
  { key: "kinki", label: "近畿", prefs: ["三重", "滋賀", "京都", "大阪", "兵庫", "奈良", "和歌山"] },
  { key: "chushi", label: "中国・四国", prefs: ["鳥取", "島根", "岡山", "広島", "山口", "徳島", "香川", "愛媛", "高知"] },
  { key: "kyushu", label: "九州", prefs: ["福岡", "佐賀", "長崎", "熊本", "大分", "宮崎", "鹿児島", "沖縄"] },
];
const REGION_OTHER = { key: "other", label: "その他", prefs: [] };   // 都道府県が分からない学校の受け皿
// 「東京都」「福井県」などの語尾は落としてそろえる（データ側は「東京」「福井」と短い形で入っている）。
// 京都府→京都、北海道→北海道。検索欄に「京都府」「福井県」と打たれても拾えるようにするための処理。
const PREF_LONG = { "東京都": "東京", "京都府": "京都", "大阪府": "大阪", "北海道": "北海道" };
const shortPref = (p) => { const s = String(p || "").trim(); return PREF_LONG[s] || s.replace(/県$/, ""); };
const REGION_OF_PREF = {};
REGIONS.forEach((r) => r.prefs.forEach((p) => { REGION_OF_PREF[p] = r.key; }));
// 学校名 → 都道府県名（無ければ空文字）
const prefOf = (team) => shortPref(((window.KANSAI && window.KANSAI.PREF) || {})[team] || "");
const regionOf = (team) => REGION_OF_PREF[prefOf(team)] || REGION_OTHER.key;

const byName = (a, b) => String(a).localeCompare(String(b), "ja");
// ラウンド種別→色分けキー。決勝に近いほど鮮やかな配色になるよう段階づけ
const roundKind = (r) => r.isFinalA ? "afinal" : r.round === "B決勝" ? "bfinal" : r.round === "準決" ? "semi" : r.round === "敗者戦" ? "cr" : "heat";
// 公式結果ページは全角英字（Ａ決勝）で書かれることがあるので、判定前に半角へそろえる
const zen = (s) => String(s || "").replace(/[Ａ-Ｚａ-ｚ０-９]/g, (c) => String.fromCharCode(c.charCodeAt(0) - 0xFEE0));
// 進出チップの色は「行き先」に合わせる（準決=紫 / A決勝=金 / B決勝=黄 / 敗者戦=グレー / それ以外=緑）。日程セルの配色と統一。
const progDest = (qRaw) => { const q = zen(qRaw); return !q ? "" : /A決勝/.test(q) ? "prog-afinal" : /B決勝/.test(q) ? "prog-bfinal" : /準決/.test(q) ? "prog-semi" : /敗者|敗復/.test(q) ? "prog-cr" : /DNS|棄権/.test(q) ? "" : "go"; };

/* 学校ページの「歴代の成績」。データは champions.js（公式「栄光の足跡」第1回〜第37回）。
   1〜3位を新しい回から並べる。最初は12件だけ出し、残りはボタンで開く。 */
function TeamHistory({ ch, evCode, rankLbl, goTab }) {
  const [all, setAll] = React.useState(false);
  const LIM = 12;
  const rows = all ? ch.rows : ch.rows.slice(0, LIM);
  const rest = ch.rows.length - rows.length;
  return (
    <div className="td-hist">
      <div className="subhead"><IconTrophy className="ic" size={16} />歴代の成績<span className="td-histed">第1回〜第37回</span></div>
      <div className="ch-detline">
        優勝 {ch.n1}回{(ch.m > 0 || ch.w > 0) ? "（男子 " + ch.m + "・女子 " + ch.w + "）" : ""}
        　2位 {ch.n2}回　3位 {ch.n3}回
      </div>
      <div className="ch-wchips">
        {rows.map((r, i) => (
          <span className={"ch-wchip" + (r.rank === 1 ? "" : " sub")} key={i}>
            <b>第{r.ed}回</b><i className="ch-wyr">（{r.year}年）</i>
            {evCode[r.ev] || r.ev}
            <em className={"td-hrk r" + r.rank}>{rankLbl[r.rank]}</em>
          </span>
        ))}
      </div>
      {rest > 0 && <button type="button" className="ch-more" onClick={() => setAll(true)}>残り{rest}件を表示</button>}
      {goTab && (
        <button type="button" className="ch-golink" onClick={() => goTab("champions")}>
          栄冠タブでほかの学校と比べる ›
        </button>
      )}
    </div>
  );
}

function TeamDetail({ team, ord, isFav, toggleFav, onClose, onOpenEvent, onSelectTeam, goTab }) {
  const RW = window.RW;
  const hideNames = !!(RW.isMinorTeam && RW.isMinorTeam(team));   // 氏名を出すかは config.js（showAthleteNames）が決める
  const t = RW.TEAMS[team];
  const [openK, setOpenK] = React.useState(null);
  React.useEffect(() => { setOpenK(null); }, [team]);
  if (!t) return null;
  const pref = prefOf(team);
  // 学校詳細の中では学校名は自明なので、クルー表記から学校名を落として A/B だけ見せる
  // （例：「浜松西高校A」→「A」）。接頭辞が一致しない稀なケースは元の表記をそのまま返す。
  const crewSuffix = (label) => {
    const s = String(label || "").trim();
    if (team && s.startsWith(team)) { const rest = s.slice(team.length).replace(/^[\s　・]+/, ""); return rest || s; }
    return s;
  };
  // 種目ごとにクルーをまとめる。並びはデータ（EVENTS）の順＝M1×→M2×→…
  const byEvent = {};
  t.crews.forEach((c) => { (byEvent[c.evKey] = byEvent[c.evKey] || []).push(c); });
  const evOrder = RW.EVENTS.map((e) => e.key);
  const evKeys = Object.keys(byEvent).sort((a, b) => evOrder.indexOf(a) - evOrder.indexOf(b));
  const prog = RW.favProgress(team);
  const isAfter = ord >= RW.LAST;   // 大会後：日程マスをやめ「最終結果」を出す

  // クルーの到達最終ラウンド＋着順から「最終結果」を作る。決勝は着順を“総合順位”に直して表示。
  //   6艇立て（A決勝＝総合1〜6位／B決勝＝総合7〜12位）。
  //   A決勝: 1/2/3＝金銀銅、4〜6＝そのまま「N位」。B決勝: 総合 = 6 + 着順（B決勝2位→総合8位）。
  //   決勝以外（準決・敗者戦・予選）は「◯◯敗退」。
  const FINAL_LANES = 6;
  const resultOf = (p) => {
    const q = zen(p.qualify), r = p.rank, R = p.lastRound;
    if (r == null && /DNS|棄権/.test(q)) return { text: "棄権", cls: "out" };
    if (R === "A決勝") {
      if (r === 1) return { medal: "金", text: "優勝", cls: "gold" };
      if (r === 2) return { medal: "銀", text: "2位", cls: "silver" };
      if (r === 3) return { medal: "銅", text: "3位", cls: "bronze" };
      return { text: r != null ? r + "位" : "決勝進出", cls: "af" };
    }
    if (R === "B決勝") return { text: r != null ? "総合" + (FINAL_LANES + r) + "位" : "出場", cls: "bf" };
    if (R === "準決") return { text: "準決敗退", cls: "sf" };
    if (R === "敗者戦") return { text: "敗者戦敗退", cls: "cr" };
    return { text: (R || "予選") + "敗退", cls: "out" };
  };

  // ── 種目×開催日のマトリクス（1種目=1行、列=大会の3日間）──
  //  ・公式結果がまだ出ていない枠 … その種目のそのラウンドの「発艇時間帯」（4組なら 10:00–13:42 の幅）。
  //    どの組で漕ぐかは当日まで決まらないので、確定時刻には見せない。
  //  ・公式結果が出た枠 … 実際の発艇時刻・組・レーンに置き換える（その学校が出た組だけ）。
  const shortRound = (r) => r.isFinalA ? "決勝" : RW.roundText(r.round);
  const norm = (s) => String(s || "").replace(/[\s　]/g, "");
  const tmin = (s) => RW.parseMin(String(s || "0:00").split("–")[0]);
  const dayIdxOfDate = (d) => {
    const n = (x) => String(x || "").replace(/^0/, "").replace("/0", "/");
    return RW.DAYS.findIndex((x) => n(x.date) === n(d));
  };
  const cellsFor = (evKey) => {
    const crews = t.crews.filter((c) => c.evKey === evKey);
    const multi = crews.length > 1;   // 同じ種目に同校が複数クルー出す場合はレーン表記で見分ける
    const isMine = (l) => multi ? crews.some((c) => norm(l.team) === norm(c.label)) : RW.baseTeam(l.team) === team;
    const cells = RW.DAYS.map(() => []);
    RW.FLAT.filter((r) => r.evKey === evKey).forEach((r) => {
      const real = RW.realRacesFor(r) || [];
      if (real.length) {
        // このラウンドは公式結果が出ている → 出た組だけを確定表示（出番が無ければ空欄のまま）
        real.forEach((kr) => {
          (kr.lanes || []).filter(isMine).forEach((l) => {
            const di = dayIdxOfDate(kr.date);
            cells[di >= 0 ? di : r.dayIndex].push({
              kind: roundKind(r), label: shortRound(r) + (kr.grp ? " " + kr.grp : ""),
              time: String(kr.time || r.t).replace(/^0/, ""), lane: l.lane, fixed: true,
            });
          });
        });
        return;
      }
      cells[r.dayIndex].push({
        kind: roundKind(r), label: shortRound(r),
        time: (r.n > 1 && r.tEnd && r.tEnd !== r.t) ? r.t + "–" + r.tEnd : r.t,
      });
    });
    return cells.map((rows) => ({ rows: rows.sort((a, b) => tmin(a.time) - tmin(b.time)) }));
  };
  // シングルスカルの氏名は公式結果に載っているので、エントリーに氏名が無ければ公式結果から拾う。
  // クルー種目のレーンには氏名が入らないため、ここで名前が出るのは 1× だけ。
  const isSingle = (ev) => /1[×xX]/.test(ev.code);
  const officialName = (evKey, crew) => {
    const rs = RW.realRaces(evKey) || [];
    for (const r of rs) {
      for (const l of (r.lanes || [])) {
        if (l.name && RW.baseTeam(l.team) === RW.baseTeam(crew.label)) return l.name;
      }
    }
    return null;
  };
  const cellsByEv = {};
  evKeys.forEach((k) => { cellsByEv[k] = cellsFor(k); });
  const hasLane = evKeys.some((k) => cellsByEv[k].some((c) => c.rows.some((x) => x.lane)));
  // 日程マスの列は大会日数に合わせる（この大会は3日間）
  const gridCols = { gridTemplateColumns: "30px repeat(" + RW.DAYS.length + ",1fr)" };

  // ── 同じ都道府県の出場校 ──────────────────────────────
  // 高校の大会は「県の代表」という見方をされるので、同じ県の学校へ横に移れるようにする。
  const sameP = pref
    ? Object.keys(RW.TEAMS).filter((x) => x !== team && prefOf(x) === pref).sort(byName)
    : [];

  // ── 歴代の成績（栄光の足跡）──────────────────────────
  // champions.jsx のヘルパーで引く。歴代に載っていない学校（26校）では何も出さない。
  const ch = (window.chRowsForTeam && window.chRowsForTeam(team)) || null;
  const chEvCode = ((window.KANSAI.CHAMPIONS || {}).meta || {}).evCode || {};
  const RANK_LBL = { 1: "優勝", 2: "2位", 3: "3位" };

  return (
    <div className="tcard">
      <div className="th" onClick={() => onClose && onClose()} style={{ cursor: onClose ? "pointer" : "default" }}>
        <span className="lanes" />
        <div className="thbtns">
          <StarBtn on={isFav} onClick={() => toggleFav(team)} size={24} />
          {onClose && <button className="closebtn" aria-label="閉じる" onClick={(e) => { e.stopPropagation(); onClose(); }}><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M6 6l12 12M18 6L6 18" /></svg></button>}
        </div>
        <h3>{team}</h3>
        <div className="meta"><span>{pref ? pref + " · " : ""}{evKeys.length}種目 · {t.crews.length}クルー</span></div>
      </div>
      <div className="tbody">
        {pref && (
          <div className="td-pref">
            {sameP.length ? (
              <React.Fragment>
                <div className="td-prefhd">{pref}の出場校<i>ほかに{sameP.length}校</i></div>
                <div className="td-prefchips">
                  {sameP.map((x) => (
                    <button type="button" className="td-prefchip" key={x}
                            onClick={() => onSelectTeam && onSelectTeam(x)} disabled={!onSelectTeam}>
                      {x}<i>{(RW.TEAMS[x] ? new Set(RW.TEAMS[x].crews.map((c) => c.evKey)).size : 0)}種目</i>
                    </button>
                  ))}
                </div>
              </React.Fragment>
            ) : (
              <div className="td-prefhd">{pref}からはこの学校だけが出場しています</div>
            )}
          </div>
        )}
        {!isAfter && (
          <React.Fragment>
            <div className="tmx-hdr" style={gridCols}>
              <span className="tmx-hlbl" />
              {RW.DAYS.map((d) => (
                <span className={"tmx-hd" + (d.dow === "土" ? " sat" : d.dow === "日" ? " sun" : "")} key={d.key}>
                  <b>{d.dow}</b><i>{d.date}</i>
                </span>
              ))}
            </div>
            <div className="tmx-leg">
              {[["#0fb5cf", "予選"], ["#9aa1ad", "敗者戦"], ["#6238cf", "準決"], ["#caa53d", "順位決定"], ["#d99a16", "決勝"]].map(([c, lb]) => (
                <span key={lb}><i style={{ background: c }} />{lb}</span>
              ))}
              {hasLane && <span className="tmx-leg-lane"><em className="tmx-lane">4<span>レーン</span></em>＝公式結果で確定</span>}
            </div>
          </React.Fragment>
        )}
        {evKeys.map((k) => {
          const ev = RW.evOf[k];
          const crews = byEvent[k];
          const op = openK === k;
          const cells = cellsByEv[k];
          const evProg = prog.filter((p) => p.evKey === k);
          return (
            <React.Fragment key={k}>
              <div className="trow clk" onClick={() => setOpenK(op ? null : k)} style={{ cursor: "pointer" }}>
                <span className="tcode"><Code ev={ev} /></span>
                <span className="tnm">{ev.name}{crews.length > 1 ? "（" + crews.length + "クルー）" : ""}</span>
                <IconChevron dir={op ? "up" : "down"} size={12} />
              </div>
              {isAfter ? (
                /* 大会後：種目ごとの最終結果（決勝は金銀銅・着順、他は「◯◯敗退」） */
                <div className="tresrow">
                  <span className="treslbl">最終結果</span>
                  {evProg.length ? evProg.map((p, i) => { const R = resultOf(p); return (
                    <span className={"tres " + R.cls} key={i}>
                      {crews.length > 1 && <b className="trescrew">{crewSuffix(p.crewLabel)}</b>}
                      {R.medal && <em className="tresmedal">{R.medal}</em>}{R.text}
                    </span>
                  ); }) : <span className="tres out">結果は結果タブへ</span>}
                </div>
              ) : (
                <React.Fragment>
                  {evProg.length > 0 && (
                    <div style={{ display: "flex", flexWrap: "wrap", gap: 5, margin: "-2px 0 8px" }}>
                      {evProg.map((p, i) => (
                        <span className={"progchip " + progDest(p.qualify)} key={i}>
                          {crews.length > 1 ? crewSuffix(p.crewLabel) + " " : ""}{p.lastRound}{p.grp ? " " + p.grp : ""}{p.rank != null ? " " + p.rank + "位" : ""}{p.qualify ? " " + p.qualify : ""}
                        </span>
                      ))}
                    </div>
                  )}
                  <div className="tmx" style={gridCols}>
                    <span className="tmx-hlbl" />
                    {cells.map((c, i) => (
                      <div className={"tmx-c" + (c.rows.length ? "" : " off")} key={i}>
                        {c.rows.length
                          ? c.rows.map((it, j) => (
                              <div className={"tmx-r " + it.kind} key={j}>
                                <i>{it.label}</i><b>{it.time}</b>
                                {it.lane && <em className="tmx-lane">{it.lane}<span>レーン</span></em>}
                              </div>
                            ))
                          : <span className="tmx-none">–</span>}
                      </div>
                    ))}
                  </div>
                </React.Fragment>
              )}
              {op && (
                <div className="trow-ros">
                  {crews.map((c) => (
                    <div className={"trow-crew" + (c.x ? " scratch" : "")} key={c.n}>
                      {crews.length > 1 && <div className="trow-crewlbl">{crewSuffix(c.label)}{c.x && <span className="rc-dnf" style={{ marginLeft: 6 }}>棄権</span>}</div>}
                      {crews.length === 1 && c.x && <div className="trow-crewlbl"><span className="rc-dnf">棄権</span></div>}
                      <div className="trow-seat">
                        {/* シングルスカルは公式結果に氏名が出るので表示。クルー種目は学校名（クルー表記）だけ。 */}
                        <span className="trow-nm">{(!hideNames && (c.name || (isSingle(ev) && officialName(k, c)))) || c.label}</span>
                      </div>
                    </div>
                  ))}
                  <button type="button" className="trow-evbtn" onClick={(e) => { e.stopPropagation(); onOpenEvent(k); }}>この種目の全クルーを見る →</button>
                </div>
              )}
            </React.Fragment>
          );
        })}
        {!isAfter && (
          <p className="tmx-note">
            時間は<b>その種目の発艇時間帯</b>（4組ある枠は最初〜最後の発艇）。どの組で漕ぐかは大会当日に決まります。
            予選より後の枠は<b>勝ち上がった場合</b>のレース時間です。公式結果が出た枠は、実際の発艇時刻・組・レーンに変わります。
          </p>
        )}
        {ch && <TeamHistory ch={ch} evCode={chEvCode} rankLbl={RANK_LBL} goTab={goTab} />}
      </div>
    </div>
  );
}

function TeamsView({ ord, favTeams, toggleFav, selectedTeam, setSelectedTeam, onOpenEvent, q, setQ, goTab }) {
  const RW = window.RW;
  const [sortMode, setSortMode] = React.useState("name");   // "name"=学校名順 / "crews"=クルー数（多い順）
  const [region, setRegion] = React.useState("all");        // "all"=全国 / 地方ブロックのキー
  const all = RW.TEAM_NAMES;
  const crewsOf = (t) => RW.TEAMS[t].crews.length;
  const cmp = sortMode === "crews" ? (a, b) => crewsOf(b) - crewsOf(a) || byName(a, b) : byName;

  const qq = String(q || "").trim();
  // 学校名でも都道府県名でも探せる（例：「静岡」で静岡県の学校が出る）
  const match = (t) => !qq || t.includes(qq) || (prefOf(t) && prefOf(t).includes(shortPref(qq)));
  const filtered = all.filter(match);
  const sorted = filtered.slice().sort(cmp);
  const favList = all.filter((t) => favTeams[t]).slice().sort(byName);
  const prefTotal = new Set(all.map(prefOf).filter(Boolean)).size;

  // 出場のある地方ブロックだけチップに出す
  const regionCount = {};
  all.forEach((t) => { const k = regionOf(t); regionCount[k] = (regionCount[k] || 0) + 1; });
  const regionList = REGIONS.concat([REGION_OTHER]).filter((r) => regionCount[r.key]);
  const regionLabel = (key) => { const r = regionList.find((x) => x.key === key); return r ? r.label : "全国"; };

  const TeamBtn = ({ t }) => {
    const T = RW.TEAMS[t];
    const p = prefOf(t);
    return (
      <button className="tbtn" onClick={() => setSelectedTeam(t === selectedTeam ? null : t)}>
        {favTeams[t] && <span className="fav-s"><Star size={11} /></span>}
        <span className="tbtn-nm">{t}</span>
        {p && <span style={{ fontSize: 10, fontWeight: 700, color: "var(--mut)" }}>/ {p}</span>}
        <span className="tbtn-stats">
          <span className="ts-x ev"><b>{T.evKeys.size}</b>種目</span>
          <span className="ts-x cr"><b>{T.crews.length}</b>クルー</span>
        </span>
      </button>
    );
  };

  // 1ブロック分の学校一覧。地方をしぼって学校名順に並べたときだけ、中を都道府県で小見出し分けする。
  const Group = ({ label, list, prefs }) => {
    if (!list.length) return null;
    const rows = [];
    if (prefs && prefs.length) {
      prefs.forEach((p) => {
        const items = list.filter((t) => prefOf(t) === p);
        if (items.length) rows.push([p, items]);
      });
      const rest = list.filter((t) => prefs.indexOf(prefOf(t)) < 0);
      if (rest.length) rows.push([null, rest]);
    } else {
      rows.push([null, list]);
    }
    return (
      <div className="tgroup">
        <div className="tgroup-h">{label}<span className="c">{list.length}</span></div>
        {rows.map(([p, items], i) => (
          <div key={p || "r" + i}>
            {p && <div className="krow-h">{p}</div>}
            <div className="tlist">{items.map((t) => <TeamBtn key={label + t} t={t} />)}</div>
          </div>
        ))}
      </div>
    );
  };

  // 地方をしぼっている / クルー数順のときは1ブロック、全国＋学校名順のときは地方ごとに分ける
  const oneBlock = region !== "all" || sortMode === "crews";
  const blockList = sorted.filter((t) => region === "all" || regionOf(t) === region);
  const subPrefs = (region !== "all" && sortMode === "name")
    ? (regionList.find((r) => r.key === region) || {}).prefs : null;

  return (
    <section className="view">
      <div className="shead"><span className="tag"><span>TEAMS</span></span><span className="jp">学校から探す</span><span className="sp" /><span className="meta">{all.length}校 · {prefTotal}都道府県</span></div>
      <div className="search"><IconSearch size={20} /><input value={q} onChange={(e) => setQ(e.target.value)} placeholder="学校名・都道府県で検索（例：浜松西、美方、静岡）" autoComplete="off" /></div>
      {selectedTeam && <TeamDetail team={selectedTeam} ord={ord} isFav={!!favTeams[selectedTeam]} toggleFav={toggleFav} onClose={() => setSelectedTeam(null)} onOpenEvent={onOpenEvent} onSelectTeam={setSelectedTeam} goTab={goTab} />}
      {!q && favList.length > 0 && (
        <div className="favsec" style={{ marginTop: 14 }}>
          <div className="favtitle"><Star size={14} color="var(--red)" />お気に入り</div>
          <div className="tlist">{favList.map((t) => <TeamBtn key={t} t={t} />)}</div>
        </div>
      )}
      {filtered.length > 0 && (
        <div className="team-sort">
          <span className="team-sort-lbl">並び替え</span>
          <button type="button" className={"chip" + (sortMode === "name" ? " on" : "")} onClick={() => setSortMode("name")}>学校名順</button>
          <button type="button" className={"chip" + (sortMode === "crews" ? " on" : "")} onClick={() => setSortMode("crews")}>クルー数</button>
        </div>
      )}
      {filtered.length > 0 && regionList.length > 1 && (
        <div className="team-sort" style={{ marginTop: 10 }}>
          <span className="team-sort-lbl">地方</span>
          <button type="button" className={"chip" + (region === "all" ? " on" : "")} onClick={() => setRegion("all")}>すべて</button>
          {regionList.map((r) => (
            <button type="button" key={r.key} className={"chip" + (region === r.key ? " on" : "")} onClick={() => setRegion(r.key)}>{r.label}</button>
          ))}
        </div>
      )}
      <div style={{ marginTop: 10 }}>
        {!filtered.length ? (
          <div className="empty">「{q}」に一致する学校はありません</div>
        ) : oneBlock ? (
          blockList.length
            ? <Group label={regionLabel(region)} list={blockList} prefs={subPrefs} />
            : <div className="empty">この地方の学校は見つかりません</div>
        ) : (
          regionList.map((r) => <Group key={r.key} label={r.label} list={sorted.filter((t) => regionOf(t) === r.key)} />)
        )}
      </div>
    </section>
  );
}
Object.assign(window, { TeamsView });
