const { useState, useMemo, useEffect } = React;

function App() {
  const D = window.RANK_DATA;

  // ----- Language -----
  const [lang, setLang] = useState(() => window.detectLang());
  useEffect(() => { localStorage.setItem("ngrk_lang", lang); }, [lang]);
  const t = useMemo(() => window.makeT(lang), [lang]);

  // ----- Data readiness gate -----
  // data.js exposes window.RANK_DATA_READY (a Promise that resolves once
  // matches.json is fetched and tier derivation populates D.brackets).
  // Until then we render a minimal loading state — but the topbar still
  // shows so the page never feels frozen.
  const [dataReady, setDataReady] = useState(false);
  useEffect(() => {
    let cancelled = false;
    const ready = window.RANK_DATA_READY;
    if (ready && typeof ready.then === "function") {
      ready.then(() => { if (!cancelled) setDataReady(true); });
    } else {
      setDataReady(true);
    }
    return () => { cancelled = true; };
  }, []);

  // ----- Availability (recomputed whenever data lands) -----
  const availability = useMemo(() => {
    const byCircuit = new Map();
    for (const cir of D.circuits) {
      const cats = new Set();
      for (const cat of D.categories) {
        if (window.dataCoverage(cir.id, cat.id).hasAny) cats.add(cat.id);
      }
      byCircuit.set(cir.id, cats);
    }
    return byCircuit;
    // dataReady flip is the signal that D.brackets has been populated
  }, [dataReady]);

  const firstCircuit  = D.circuits.find(c => availability.get(c.id)?.size > 0)?.id  || D.circuits[0].id;
  const firstCategory = [...(availability.get(firstCircuit) || [])][0] || D.categories[0].id;

  const [circuit, setCircuit]   = useState(firstCircuit);
  const [category, setCategory] = useState(firstCategory);
  const [search, setSearch]     = useState("");

  // When data lands after first render, snap to the first available pair so
  // the user isn't staring at an empty default circuit when there's real
  // data sitting on a different one.
  useEffect(() => {
    if (!dataReady) return;
    const cats = availability.get(circuit) || new Set();
    if (cats.size === 0) {
      const fc = D.circuits.find(c => availability.get(c.id)?.size > 0)?.id;
      if (fc) {
        setCircuit(fc);
        setCategory([...(availability.get(fc) || [])][0] || category);
      }
    } else if (!cats.has(category)) {
      setCategory([...cats][0] || category);
    }
  }, [dataReady]);

  const onCircuitChange = (id) => {
    setCircuit(id);
    const cats = availability.get(id) || new Set();
    if (!cats.has(category)) setCategory([...cats][0] || category);
  };

  const rows     = useMemo(() => window.buildClassification(circuit, category), [circuit, category, dataReady]);
  const coverage = useMemo(() => window.dataCoverage(circuit, category),       [circuit, category, dataReady]);

  const stagesForView = useMemo(() => {
    const ids = new Set(coverage.stagesWithData);
    return D.stages.filter(s => ids.has(s.id));
  }, [coverage.stagesWithData.join(",")]);

  const latestStage = D.stages.find(s => s.id === coverage.latestStageId);
  const latestShort = latestStage ? latestStage.label.replace(" Etapa", "") : "";

  const availableCircuits   = new Set([...availability].filter(([, v]) => v.size).map(([k]) => k));
  const availableCategories = availability.get(circuit) || new Set();

  const cirObj = D.circuits.find(c => c.id === circuit);
  const catObj = D.categories.find(c => c.id === category);

  const updatedStr = useMemo(() => {
    if (!D.extractedAt) return "—";
    const extracted = new Date(D.extractedAt);
    if (Number.isNaN(extracted.getTime())) return "—";
    return extracted.toLocaleDateString(t.dict.locale, {
      day: "2-digit", month: "short", year: "numeric",
    });
  }, [dataReady, lang]);

  return (
    <main className="page">
      <header className="topbar">
        <div className="brand">
          <span className="brand__mark" aria-hidden="true">
            <svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="#1f8a5b" strokeWidth="2">
              <circle cx="12" cy="12" r="9"/>
              <circle cx="12" cy="12" r="3.5" fill="#1f8a5b"/>
            </svg>
          </span>
          <div>
            <div className="brand__name">NextGen Ranking</div>
            <div className="brand__tag">{t("brandTag")}</div>
          </div>
        </div>
        <div className="topbar__right">
          <LangSwitch langs={window.LANGS} current={lang} onChange={setLang} />
          <div className="updated">
            <span className="updated__dot" aria-hidden="true"></span>
            <span>{t("updated")} {updatedStr}</span>
          </div>
        </div>
      </header>

      {!dataReady ? (
        <div className="empty" role="status" aria-live="polite">
          <div className="empty__title">{t("updated")}…</div>
        </div>
      ) : (
        <>
          <div className="pills-row">{t("circuit")}</div>
          <Pills
            items={D.circuits}
            current={circuit}
            available={availableCircuits}
            onChange={onCircuitChange}
            t={t}
          />

          <div className="pills-row">{t("category")}</div>
          <Pills
            items={D.categories}
            current={category}
            available={availableCategories}
            onChange={setCategory}
            t={t}
          />

          <div className="tablehead">
            <div className="tablehead__title">
              {cirObj?.label} · {catObj?.label}
            </div>
            <div className="tablehead__count">{t("players", rows.length)}</div>
          </div>

          {rows.length > 0 && (
            <div className="search">
              <span className="search__icon" aria-hidden="true">⌕</span>
              <input
                type="search"
                placeholder={t("filter")}
                value={search}
                onChange={(e) => setSearch(e.target.value)}
                className="search__input"
              />
            </div>
          )}

          <ClassificationTable
            rows={rows}
            search={search}
            latestStageShort={latestShort}
            stages={stagesForView}
            scoring={D.scoring}
            t={t}
            circuit={circuit}
            category={category}
          />

          <ScoringDisclose scoring={D.scoring} t={t} />
        </>
      )}

      <footer className="footer">
        {t("footerPrefix")}
        <a href="https://supertie.link/" target="_blank" rel="noreferrer">supertie.link</a>
        {t("footerSuffix")}
      </footer>
    </main>
  );
}

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