/* =============================================================================
 * PUBLIC TOURNAMENT RESULTS (/results) — signed-out, no account required.
 * =============================================================================
 * Now that the contest is closed, a newcomer who lands on the waitlist has no way to see
 * how the tournament actually went: the group tables and bracket live behind the auth gate
 * and the landing page's demos are hand-authored. This page fills that gap — it is the
 * second half of the waitlist's thank-you CTAs ("See the results" / "World Cup 101").
 *
 * It renders the REAL tournament with the app's OWN screens: `computeGroupTables` +
 * `GroupTable` + `KnockoutBracket` (screens-tournament.jsx) derive everything purely from
 * `window.ACQ.MATCHES` + `TEAMS`, so we fetch the public results feed
 * (GET /api/public/results → src/publicResults.js: teams, venues, fixtures — no players,
 * picks or standings) and assign it to `window.ACQ`, exactly as the TV kiosk does. Nothing
 * else is duplicated: the tables and the bracket are the same components signed-in players
 * see on /standings.
 *
 * `window.ACQ` is restored on unmount so a partial payload can never outlive the page (the
 * signed-in bootstrap would overwrite it anyway, but a signed-out visitor bouncing between
 * this page and the landing shouldn't leave one behind).
 *
 * The shell is the shared `PublicShell` (screens-landing.jsx): one sticky topnav, one menu
 * and one footer across all three pre-login surfaces, so they are indistinguishable in style
 * and a visitor gets the same navigation wherever they land.
 * ========================================================================= */

function Results({ onBack, onSignIn, onJoin, onResults, onWorldCup101, signupsOpen = true, season }) {
  const [payload, setPayload] = React.useState(null);
  const [err, setErr] = React.useState(null);
  // Bumped by the error card's "Try again" — re-runs the fetch effect below, so a visitor who
  // hit a cold start doesn't have to wait out the heartbeat.
  const [attempt, setAttempt] = React.useState(0);
  // Bumped on every (re)load so the tournament sections re-render off the new window.ACQ —
  // the components read the global during render, not a prop.
  const [version, setVersion] = React.useState(0);

  const seasonLabel = (season && season.season) || (payload && payload.tournamentName) || "World Cup 2026";
  const champion = season && season.champion;
  const joinLabel = signupsOpen ? "Join the contest" : "Get notified";
  const scrollTo = (id) => { const el = document.getElementById(id); if (el) el.scrollIntoView({ behavior: "smooth", block: "start" }); };

  // Fetch, then keep two cadences (the kiosk's): 60s while a match is live or near kickoff
  // (`active` — the same signal the kiosk and the in-app auto-refresh use), and a slow 15-min
  // heartbeat otherwise. The heartbeat is what lets a page opened BEFORE kickoff notice the
  // live window opening; polling only while already active would leave it on a stale scoreline
  // for the whole match. A settled tournament costs four server-cached requests an hour.
  React.useEffect(() => {
    let live = true;
    const prevAcq = window.ACQ;
    let timer = null;
    // Whether the last good payload was inside a live window. Tracked in the closure rather
    // than read off `payload`, which this []-dep effect would only ever see as null.
    let active = false;
    // Always reschedule, including after a FAILURE — otherwise one cold start or moment
    // offline ends the refresh for the life of the page and the scores silently freeze
    // mid-match. Only an unmount (`live`) stops the loop.
    const schedule = () => { if (live) timer = setTimeout(load, active ? 60000 : 900000); };
    const load = () => {
      API.publicResults().then((p) => {
        if (!live) return;
        window.ACQ = p;
        setPayload(p);
        setErr(null);
        setVersion((v) => v + 1);
        active = !!(p && p.active);
        schedule();
      }).catch((e) => {
        if (!live) return;
        setErr((e && e.error) || "We couldn't load the results just now. Please try again.");
        schedule();
      });
    };
    load();
    return () => {
      live = false;
      if (timer) clearTimeout(timer);
      window.ACQ = prevAcq;
    };
    // `attempt` only ever changes while the error card is up, i.e. while nothing has been
    // assigned to window.ACQ yet, so the re-run captures the same untouched prevAcq.
  }, [attempt]);

  // SEO: swap in this page's own title + meta description while it is on screen, restored
  // on unmount — the same pattern the WC101 primer uses. Crawlers that don't run JS get the
  // same head server-side (src/seo.js buildResultsHtml, served for /results by the SPA
  // fallback); keep these two strings in sync with RESULTS_TITLE/RESULTS_DESCRIPTION there.
  React.useEffect(() => {
    const meta = document.querySelector('meta[name="description"]');
    const prev = { title: document.title, desc: meta && meta.getAttribute("content") };
    document.title = "World Cup 2026 Results: Final Score, Group Tables and Full Bracket | AcquiCup";
    if (meta) meta.setAttribute("content", "How the 2026 World Cup finished: Spain beat Argentina 1-0 after extra time on 19 July 2026. Every group table and the complete knockout bracket from the round of 32 to the final, free and without an account.");
    return () => {
      document.title = prev.title;
      if (meta && prev.desc != null) meta.setAttribute("content", prev.desc);
    };
  }, []);

  const A = payload;
  const groupTables = React.useMemo(() => {
    if (!A) return [];
    return computeGroupTables(A.MATCHES.filter((m) => m.stage === "Group Stage")).filter((t) => t.group !== "—");
  }, [version]);
  const hasKO = !!(A && A.MATCHES.some((m) => m.stage && m.stage !== "Group Stage"));

  const body = (
    <div className="col gap-24">

      {/* ---------- hero (hero-card pattern, same as the WC101 primer) ---------- */}
      <div className="card hero-card" style={{ background: "var(--hero-bg)", color: "var(--hero-ink)", border: "none", overflow: "hidden", position: "relative" }}>
        <div style={{ position: "absolute", inset: 0, opacity: .5, background: "radial-gradient(700px 240px at 88% -30%, color-mix(in srgb, var(--brand-blue) 40%, transparent), transparent)" }} />
        <svg style={{ position: "absolute", right: 0, top: 0, height: "100%", opacity: .12 }} width="320" height="220" viewBox="0 0 320 220" fill="none" stroke="white" strokeWidth="1.5">
          <circle cx="300" cy="110" r="60" /><line x1="300" y1="0" x2="300" y2="220" /><rect x="250" y="70" width="80" height="80" />
        </svg>
        <div className="card-pad" style={{ padding: "26px 28px", position: "relative" }}>
          <div className="col gap-2" style={{ minWidth: 0, maxWidth: 660 }}>
            <span className="eyebrow" style={{ color: "color-mix(in srgb, var(--hero-ink) 70%, transparent)" }}>{seasonLabel} · Final results</span>
            <h1 style={{ fontSize: 30, marginTop: 8, fontWeight: 800, letterSpacing: "-.03em", lineHeight: 1.08 }}>
              {champion ? champion + " won the " + seasonLabel + "." : "How the " + seasonLabel + " finished."}
            </h1>
            <span style={{ opacity: .82, fontSize: 14.5, marginTop: 10, lineHeight: 1.55 }}>
              Every group table and the full knockout bracket, exactly as the players saw them, on the same screens the contest ran on. No account needed.
            </span>
            {A && (
              <div className="row gap-20 wrap" style={{ marginTop: 18 }}>
                <div className="col"><span className="mono" style={{ fontSize: 22, fontWeight: 700 }}>{A.summary.played}</span><span style={{ opacity: .7, fontSize: 12 }}>matches played</span></div>
                <div className="col"><span className="mono" style={{ fontSize: 22, fontWeight: 700 }}>{A.summary.goals}</span><span style={{ opacity: .7, fontSize: 12 }}>goals scored</span></div>
                <div className="col"><span className="mono" style={{ fontSize: 22, fontWeight: 700 }}>{A.summary.teams}</span><span style={{ opacity: .7, fontSize: 12 }}>teams</span></div>
              </div>
            )}
            <div className="row gap-10 wrap" style={{ marginTop: 18 }}>
              {hasKO && <button className="btn btn-primary" onClick={() => scrollTo("bracket")}>Jump to the bracket ↓</button>}
              <button className="btn btn-ghost on-hero" onClick={onWorldCup101}>World Cup 101<Icon name="chevron" size={15} /></button>
            </div>
          </div>
        </div>
      </div>

      {/* ---------- loading / error ---------- */}
      {!A && !err && (
        <div className="card card-pad col center gap-10" style={{ padding: 48, textAlign: "center" }}>
          <span className="muted" style={{ fontSize: 13.5 }}>Loading the results…</span>
        </div>
      )}
      {/* Only when there is nothing to show: a failed POLL leaves the last good tables up
          (they are still real results) rather than stacking this card on top of them. */}
      {err && !A && (
        <div className="card card-pad col center gap-12" style={{ padding: 44, textAlign: "center" }}>
          <span style={{ fontWeight: 700, fontSize: 16 }}>Results unavailable</span>
          <span className="muted" style={{ fontSize: 13.5, maxWidth: 420 }}>{err}</span>
          <div className="row gap-10 wrap center">
            <button className="btn btn-primary btn-sm" onClick={() => { setErr(null); setAttempt((n) => n + 1); }}>Try again</button>
            <button className="btn btn-ghost btn-sm" onClick={onBack}>Back to the homepage</button>
          </div>
        </div>
      )}

      {/* ---------- group stage — the app's own GroupTable, off the public feed ---------- */}
      {A && (
        <div className="col gap-12" id="groups">
          <PageHead level={2} eyebrow="Tournament" title="Group stage"
            sub="Three points for a win, one for a draw. The top two of each group, plus the eight best third-placed teams, advanced to the Round of 32." />
          {groupTables.length === 0 ? (
            <div className="card card-pad col center gap-10" style={{ padding: 40, textAlign: "center" }}>
              <Icon name="table" size={28} style={{ color: "var(--ink-soft)" }} />
              <span className="muted" style={{ fontSize: 13.5 }}>No group-stage fixtures are loaded yet.</span>
            </div>
          ) : (
            <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill,minmax(min(100%,340px),1fr))", gap: 16, alignItems: "start" }}>
              {groupTables.map((t) => (
                <GroupTable key={t.group} title={"Group " + t.group} rows={t.rows} showQ={t.rows.length >= 4} />
              ))}
            </div>
          )}
        </div>
      )}

      {/* ---------- knockout bracket — the in-app component, standalone (its own head +
           champion banner). No openMatch: match detail pages are for signed-in players. ---------- */}
      {A && hasKO && (
        <div id="bracket">
          <KnockoutBracket go={() => {}} />
        </div>
      )}

      {/* ---------- closing CTA (hero-card, mirroring WC101's) ---------- */}
      <div className="card hero-card" style={{ background: "var(--hero-bg)", color: "var(--hero-ink)", border: "none", overflow: "hidden", position: "relative" }}>
        <div style={{ position: "absolute", inset: 0, opacity: .5, background: "radial-gradient(700px 240px at 12% -30%, color-mix(in srgb, var(--brand-blue) 40%, transparent), transparent)" }} />
        <div className="card-pad row between wrap gap-16" style={{ padding: "26px 28px", position: "relative", alignItems: "center" }}>
          <div className="col gap-2" style={{ minWidth: 0 }}>
            <h2 style={{ fontSize: 24, fontWeight: 800, letterSpacing: "-.03em" }}>
              {signupsOpen ? "Think you can call the next one?" : "Ready for the next one?"}
            </h2>
            <span style={{ opacity: .82, fontSize: 14, marginTop: 4 }}>
              {signupsOpen
                ? "Predict every scoreline, double your two best shots and take on the rest of the office."
                : "Predictions for the next AcquiCup open before the first kick-off. Be first in line."}
            </span>
          </div>
          <div className="row gap-10 wrap">
            <button className="btn btn-primary" onClick={onJoin}>{joinLabel}<Icon name="chevron" size={15} /></button>
            <button className="btn btn-ghost on-hero" onClick={onWorldCup101}>World Cup 101</button>
          </div>
        </div>
      </div>

    </div>
  );

  // The shell is the shared signed-out one (screens-landing.jsx): same topnav, same menu,
  // same footer as the homepage and the World Cup 101 primer.
  return (
    <PublicShell page="results" onHome={onBack} onResults={onResults} onWorldCup101={onWorldCup101}
      onSignIn={onSignIn} onJoin={onJoin} signupsOpen={signupsOpen}>
      {body}
    </PublicShell>
  );
}

Object.assign(window, { Results });
