/* App shell -- hash-based routing + mobile-first responsive layout.
   Routes: home, predict, dashboard (public), admin (full-screen). */

function useHashRoute() {
  const get = () => {
    const h = (window.location.hash || '').replace(/^#\/?/, '');
    if (h === 'predict')          return 'predict';
    if (h === 'fixtures')         return 'fixtures';
    if (h === 'dashboard')        return 'dashboard';
    if (h === 'my-predictions')   return 'my-predictions';
    if (h === 'penguin-hq' || h.startsWith('penguin-hq/')) return 'admin';
    if (h === 'about') return 'about';
    if (h === 'terms') return 'terms';
    return 'home';
  };
  const [route, setRoute] = useState(get());
  useEffect(() => {
    const fn = () => setRoute(get());
    window.addEventListener('hashchange', fn);
    return () => window.removeEventListener('hashchange', fn);
  }, []);
  const nav = (to) => {
    window.location.hash = `#/${to === 'home' ? '' : to}`;
    if (to !== 'fixtures') {
      window.scrollTo({ top: 0, behavior: 'smooth' });
    }
  };
  return [route, nav];
}

/* Per-route SEO: title, description, OG/Twitter, robots.
   Static <head> in index.html covers the default (home) state for first paint /
   social-card scrapers; this keeps in-app navigation (hash routes) in sync for
   crawlers that execute JS and for the document title shown in browser tabs. */
var ROUTE_SEO = {
  home: {
    title: 'SunFront World Cup Foari 2026 — Predict Matches & Win Prizes | Maldives',
    description: "Join SunFront's FIFA World Cup 2026 prediction game. Pick match winners, climb the leaderboard, and win prizes from DKAA, Samsung, KDK, JBL, Hatari, Makute & Truemark.",
  },
  fixtures: {
    title: 'FIFA World Cup 2026 Fixtures & Schedule (Maldives Time) | SunFront',
    description: 'Full FIFA World Cup 2026 match schedule in Maldives time (MVT) — group stage through the Final, with kickoff times, venues and stage labels.',
  },
  predict: {
    title: 'Make Your Predictions | SunFront World Cup Foari 2026',
    description: 'Submit your FIFA World Cup 2026 match predictions and compete for prizes on the SunFront leaderboard.',
  },
  dashboard: {
    title: 'Leaderboard & Standings | SunFront World Cup Foari 2026',
    description: 'See the top predictors and live standings in the SunFront FIFA World Cup 2026 prediction competition.',
  },
  'my-predictions': {
    title: 'My Predictions | SunFront World Cup Foari 2026',
    description: 'Review your submitted FIFA World Cup 2026 match predictions.',
    noindex: true,
  },
  admin: {
    title: 'Admin | SunFront World Cup Foari 2026',
    noindex: true,
  },
  about: {
    title: 'About SunFront World Cup Foari 2026',
    description: 'About the SunFront World Cup Foari 2026 prediction campaign — an independent fan competition based in Malé, Maldives. Not affiliated with FIFA.',
  },
  terms: {
    title: 'Terms & Conditions | SunFront World Cup Foari 2026',
    description: 'Terms and conditions for the SunFront World Cup Foari 2026 prediction competition.',
  },
};

function useSEOMeta(route) {
  useEffect(() => {
    var seo = ROUTE_SEO[route] || ROUTE_SEO.home;
    document.title = seo.title;
    var setMeta = function (name, content, attr) {
      attr = attr || 'name';
      var sel = 'meta[' + attr + '="' + name + '"]';
      var el = document.head.querySelector(sel);
      if (!el) {
        el = document.createElement('meta');
        el.setAttribute(attr, name);
        document.head.appendChild(el);
      }
      el.setAttribute('content', content);
    };
    setMeta('og:title', seo.title, 'property');
    setMeta('twitter:title', seo.title);
    if (seo.description) {
      setMeta('description', seo.description);
      setMeta('og:description', seo.description, 'property');
      setMeta('twitter:description', seo.description);
    }
    setMeta('robots', seo.noindex ? 'noindex, nofollow' : 'index, follow');
  }, [route]);
}

function ResponsiveStyles() {
  return (
    <style>{`
      /* Mobile-only elements -- hidden on desktop, shown via media query */
      .mobile-hero-slide-wrap { display: none; }
      .mobile-sub-banner { display: none; }

      /* Sponsor advertising banners -- desktop image vs mobile (390x80) image */
      .sponsor-desktop-banner { display: block; }
      .sponsor-mobile-banner { display: none; }

      /* Grand prize product banner -- removed from desktop, section collapses */
      .product-banner-section { display: none; }

      /* Hero logo wrapper -- transparent on desktop, positioning anchor on mobile */
      .hero-logo-mobile-anchor { display: contents; }

      /* ── Hero background fill ── */
      @media (max-width: 920px) {
        .hero-section {
          background-size: cover !important;
          background-position: 60% center !important;
        }
      }
      /* Mobile: cover + shift right + top-to-bottom scrim */
      @media (max-width: 600px) {
        .hero-section {
          background-size: cover !important;
          background-position: 70% center !important;
        }
        .hero-scrim {
          background: linear-gradient(
            to bottom,
            rgba(255,255,255,0.85) 0%,
            rgba(255,255,255,0.70) 50%,
            rgba(255,255,255,0.40) 80%,
            rgba(255,255,255,0.08) 100%
          ) !important;
        }
      }

      /* ── Hero mobile: logo first, full-width banner, text centered ── */
      @media (max-width: 720px) {
        /* Logo column: edge-to-edge, aspect-ratio drives height from banner ratio */
        .hero-logo-col {
          order: -1 !important;
          width: 100vw !important;
          margin-left: calc(-1 * clamp(16px,4vw,22px)) !important;
          padding: 0 !important;
          overflow: hidden !important;
          position: relative !important;
          aspect-ratio: 750 / 350 !important;
          align-items: unset !important;
          justify-content: unset !important;
        }
        /* Logo anchor floats bottom-center over banner -- holds the static
           position so the img itself stays free for the 3D wave animation */
        .hero-logo-mobile-anchor {
          display: block !important;
          position: absolute !important;
          bottom: 28px !important;
          left: 50% !important;
          transform: translateX(-50%) !important;
          max-width: 180px !important;
          width: 48% !important;
          z-index: 2 !important;
        }
        .hero-logo-col img.divehi-wave {
          position: relative !important;
          width: 100% !important;
          max-width: none !important;
          margin: 0 !important;
        }
        .mobile-hero-slide-wrap { display: block !important; }
        .sponsor-desktop-banner { display: none !important; }
        .sponsor-mobile-banner { display: block !important; }
        .hero-section { background-image: none !important; overflow: hidden !important; }
      }

      /* ── Next-up countdown: keep within card on mobile ── */
      @media (max-width: 720px) {
        .next-up-card { padding: 32px 14px !important; }
        .big-countdown { gap: 4px !important; }
        .big-countdown-seg { min-width: 50px !important; padding: 6px 3px 4px !important; }
        .big-countdown-seg .seg-value { font-size: 20px !important; }
        .big-countdown-seg .seg-label { font-size: 8px !important; margin-top: 2px !important; }
        .big-countdown-colon { font-size: 16px !important; }
      }
      @media (max-width: 360px) {
        .next-up-card { padding: 24px 10px !important; }
        .big-countdown { gap: 2px !important; }
        .big-countdown-seg { min-width: 44px !important; padding: 5px 2px 3px !important; }
        .big-countdown-seg .seg-value { font-size: 17px !important; }
        .big-countdown-colon { font-size: 13px !important; }
      }

      /* ── Grid breakpoints ── */
      @media (max-width: 920px) {
        .hero-grid       { grid-template-columns: 1fr !important; gap: 20px !important; }
        .step-grid       { grid-template-columns: repeat(2, 1fr) !important; }
        .dash-grid       { grid-template-columns: 1fr !important; }
        .topstats-grid   { grid-template-columns: repeat(2, 1fr) !important; }
        .open-matches    { display: flex !important; gap: 12px; overflow-x: auto; scroll-snap-type: x mandatory; padding: 4px 4px 16px; }
        .open-matches::-webkit-scrollbar { display: none; }
        .open-matches > * { flex: 0 0 84%; max-width: 320px; scroll-snap-align: start; }
        .admin-2col      { grid-template-columns: 1fr !important; }
      }
      @media (min-width: 921px) {
        .open-matches { display: grid !important; grid-template-columns: repeat(3, 1fr); gap: 18px; }
      }
      /* Desktop hero: size section to banner's aspect ratio so full image shows, no crop */
      @media (min-width: 721px) {
        .hero-section { aspect-ratio: 1920 / 700; margin-bottom: 5px; }
        .hero-grid    { min-height: 0 !important; padding: 0 !important; }
      }
      @media (max-width: 720px) {
        .step-grid       { grid-template-columns: 1fr 1fr !important; gap: 10px !important; }
        .rules-grid      { grid-template-columns: 1fr !important; }
        .prizes-grid     { grid-template-columns: 1fr !important; gap: 10px !important; }
        .form-grid       { grid-template-columns: 1fr !important; gap: 12px !important; }
        .pick-grid       { grid-template-columns: 1fr !important; gap: 10px !important; }
        .topstats-grid   { grid-template-columns: 1fr 1fr !important; gap: 10px !important; }
        .outlet-row      { grid-template-columns: 90px 1fr 48px !important; gap: 8px !important; }
        .match-row       { padding: 14px 12px 10px !important; }
        /* Compact page-band on mobile */
        .page-band-inner { padding: 20px 16px 16px !important; }
        /* Tighten section paddings */
        section          { padding-left: 0 !important; padding-right: 0 !important; }
      }
      @media (max-width: 480px) {
        .step-grid       { grid-template-columns: 1fr !important; gap: 10px !important; }
        .pick-grid       { grid-template-columns: repeat(3, 1fr) !important; }
        /* Outlet row shrink */
        .outlet-row      { grid-template-columns: 76px 1fr 42px !important; gap: 6px !important; }
        /* Hero grid: no top padding so banner sits right under navbar, 2px below */
        .hero-grid       { padding-top: 0 !important; padding-bottom: 2px !important; }
      }

      /* ── Fixture row: stack teams + full-width pick on mobile ── */
      @media (max-width: 600px) {
        .fixture-row { grid-template-columns: auto 1fr !important; gap: 8px !important; }
        .fixture-row > *:last-child { grid-column: 1 / -1 !important; justify-self: stretch !important; text-align: center !important; padding: 10px !important; border-radius: 6px !important; }
        .fixture-teams { flex-direction: column !important; align-items: flex-start !important; gap: 5px !important; }
        .fixture-vs { display: none !important; }
        .fixture-team { flex-direction: row !important; align-items: center !important; width: 100% !important; }
        .fixture-name { white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important; font-size: 13px !important; }
      }

      /* ── Nav logo smooth sizing ── */
      @media (max-width: 600px) {
        .nav-campaign-logo { height: 60px !important; }
      }

      /* ── BottomNav clearance matches taller nav ── */
      @media (max-width: 720px) {
        .has-bottom-nav-mobile { padding-bottom: calc(68px + env(safe-area-inset-bottom)) !important; }
      }

      /* ── Ticker compact on mobile ── */
      @media (max-width: 600px) {
        .ticker-track    { gap: 28px !important; }
      }

      /* ── Nav compact on mobile ── */
      @media (max-width: 720px) {
        .nav-inner       { padding-top: 4px !important; padding-bottom: 4px !important; }
        .nav-campaign-logo { height: 70px !important; }
      }

      /* ── Banner strip logo pill compact on mobile ── */
      @media (max-width: 600px) {
        .banner-logo-pill        { padding: 7px 18px !important; border-radius: 8px !important; }
        .banner-logo-pill img    { height: 46px !important; }
        .inner-banner-img        { max-height: 110px !important; }
        .inner-banner-logo       { height: 60px !important; }
      }

      /* ── Fix pick buttons on narrow mobile -- keep 3-column ── */
      @media (max-width: 380px) {
        .pick-grid       { gap: 6px !important; }
      }

      /* ── Footer compact ── */
      @media (max-width: 720px) {
        footer           { margin-top: 40px !important; }
        .footer-inner    { flex-direction: column !important; gap: 16px !important; text-align: center !important; align-items: center !important; }
        .footer-inner > div:first-child { display: flex; flex-direction: column; align-items: center; }
        .footer-links    { text-align: center !important; align-items: center !important; }
        .footer-links > div { justify-content: center !important; }
        .footer-logo-pill { height: 56px !important; }
      }

      /* ── InnerPageBanner: don't crush on phone ── */
      @media (max-width: 480px) {
        .page-band-inner h1 { font-size: 28px !important; line-height: 1.1 !important; }
      }
    `}</style>
  );
}

function PublicShell({ route, nav, children }) {
  return (
    <div data-screen-label={
      route === 'predict'        ? 'Predict' :
      route === 'fixtures'       ? 'Fixtures' :
      route === 'dashboard'      ? 'Live Stats' :
      route === 'my-predictions' ? 'My Predictions' : 'Home'
    } className="has-bottom-nav-mobile" style={{ minHeight: '100vh' }}>
      <ResponsiveStyles />
      <style>{`
        @media (max-width: 720px) {
          .has-bottom-nav-mobile { padding-bottom: calc(60px + env(safe-area-inset-bottom)); }
        }
      `}</style>
      <MatchTicker matches={MATCHES} />
      <Nav route={route} onNav={nav} />
      {children}
      <Footer />
      <BottomNav route={route} onNav={nav} />
    </div>
  );
}

function useLiveMatches() {
  const [, forceUpdate] = React.useReducer(x => x + 1, 0);

  useEffect(() => {
    let active = true;

    async function refresh() {
      try {
        const res = await fetch('/api/matches');
        if (!res.ok || !active) return;
        const data = await res.json();
        if (!Array.isArray(data.matches) || data.matches.length === 0) return;

        // Rebuild match objects (kickoffAt must be a Date; API sends kickoffMs)
        const updated = data.matches.map(m => ({
          ...m,
          kickoffAt: new Date(m.kickoffMs),
        }));

        // Mutate the shared MATCHES array in-place -- all components re-read it
        window.MATCHES.splice(0, window.MATCHES.length, ...updated);
        if (active) forceUpdate();
      } catch (_) { /* keep static data on network error */ }
    }

    refresh();
    const timer = setInterval(refresh, 5 * 60 * 1000); // re-fetch every 5 min
    return () => { active = false; clearInterval(timer); };
  }, []);
}

const FIGURINE_MAP = {
  home:             ['messi',      'ronaldo'],
  fixtures:         ['mbappe',     'haaland'],
  predict:          ['vinicius',   'bellingham'],
  dashboard:        ['kane',       'yamal'],
  'my-predictions': ['pulisic',    'haaland'], // haaland intentionally reused — only 9 players available
};

function FigurineLayer({ route }) {
  const pair = FIGURINE_MAP[route];
  if (!pair) return null;
  return (
    <>
      <div className="figurine-layer figurine-left">
        <video key={pair[0]} autoPlay loop muted playsInline>
          <source src={`/assets/figurines/webm/${pair[0]}.webm`} type="video/webm" />
          <img src={`/assets/figurines/gif/${pair[0]}.gif`} alt={pair[0]} />
        </video>
      </div>
      <div className="figurine-layer figurine-right">
        <video key={pair[1]} autoPlay loop muted playsInline>
          <source src={`/assets/figurines/webm/${pair[1]}.webm`} type="video/webm" />
          <img src={`/assets/figurines/gif/${pair[1]}.gif`} alt={pair[1]} />
        </video>
      </div>
    </>
  );
}

function App() {
  const [route, nav] = useHashRoute();
  const [customFlags, setCustomFlags] = useState({});
  useLiveMatches();
  useSEOMeta(route);

  useEffect(() => {
    fetch('/api/flags')
      .then(r => r.ok ? r.json() : {})
      .then(data => { if (data && typeof data === 'object') setCustomFlags(data); })
      .catch(() => {});
  }, []);

  if (route === 'admin') {
    return (
      <CustomFlagsCtx.Provider value={customFlags}>
      <div data-screen-label="Admin">
        <AdminApp onLeave={() => nav('home')} />
      </div>
      </CustomFlagsCtx.Provider>
    );
  }

  return (
    <CustomFlagsCtx.Provider value={customFlags}>
    <PublicShell route={route} nav={nav}>
      {route === 'home'           && <HomePage onNav={nav} />}
      {route === 'fixtures'       && <FixturesPage onNav={nav} />}
      {route === 'predict'        && <PredictPage />}
      {route === 'dashboard'      && <DashboardPage />}
      {route === 'my-predictions' && <MyPredictionsPage />}
      {route === 'about'          && <AboutPage />}
      {route === 'terms'          && <TermsPage />}
    </PublicShell>
    <FigurineLayer route={route} />
    </CustomFlagsCtx.Provider>
  );
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
