/* global React, ReactDOM, HomePage, TopPicksPage, CategoryPage, MarketPage, LeaderboardPage, ProfilePage, SharePage, SuggestPage, UserMenu, SignInButton, CategoryDropdown, useAuth, useMeta */

const { useState, useEffect, useCallback } = React;

// ── History-API router ─────────────────────────────────────────────────────
// Real paths (no more #/), so refresh / share / SEO behaves like a normal
// website. The Node server has a catch-all that serves index.html for any
// non-API path, so /upgrade reloads correctly.
//   /                           → home
//   /toppicks                   → ad-ready Top Picks page
//   /category/:slug             → category browse
//   /market/:polymarketId       → market detail
//   /leaderboard                → official + community
//   /track                      → user's tracked prompts (auth-gated)
//   /og[/:id]                   → share-card preview
//   /suggest, /upgrade          → static pages
function parseRoute(pathname) {
  const clean = (pathname || '/').replace(/^\/+/, '').replace(/\/+$/, '');
  if (!clean) return { page: 'home', params: {} };
  const [head, ...rest] = clean.split('/');
  switch (head) {
    case 'toppicks':    return { page: 'toppicks', params: {} };
    case 'category':    return { page: 'category', params: { slug: rest[0] || '' } };
    case 'market':      return { page: 'market', params: { id: rest.join('/') } };
    case 'leaderboard': return { page: 'leaderboard', params: {} };
    case 'track':       return { page: 'profile', params: {} };
    case 'og':          return { page: 'share', params: { id: rest[0] || '' } };
    case 'suggest':     return { page: 'suggest', params: {} };
    case 'upgrade':     return { page: 'upgrade', params: {} };
    default:            return { page: 'home', params: {} };
  }
}
function routeToPath(page, params = {}) {
  switch (page) {
    case 'home':        return '/';
    case 'toppicks':    return '/toppicks';
    case 'category':    return `/category/${encodeURIComponent(params.slug || '')}`;
    case 'market':      return `/market/${encodeURIComponent(params.id || '')}`;
    case 'leaderboard': return '/leaderboard';
    case 'profile':     return '/track';
    case 'share':       return params.id ? `/og/${encodeURIComponent(params.id)}` : '/og';
    case 'suggest':     return '/suggest';
    case 'upgrade':     return '/upgrade';
    default:            return '/';
  }
}

function useRoute() {
  const [route, setRoute] = useState(() => parseRoute(window.location.pathname));
  useEffect(() => {
    const onPop = () => setRoute(parseRoute(window.location.pathname));
    window.addEventListener('popstate', onPop);
    return () => window.removeEventListener('popstate', onPop);
  }, []);
  const navigate = useCallback((page, params = {}) => {
    const target = routeToPath(page, params);
    const current = window.location.pathname + window.location.search;
    if (current !== target) {
      window.history.pushState({}, '', target);
      setRoute(parseRoute(target));
    } else {
      // Same path — force re-render
      setRoute(parseRoute(target));
    }
    window.scrollTo(0, 0);
  }, []);
  return { route, navigate };
}

// ── Nav ────────────────────────────────────────────────────────────────────
function Nav({ route, navigate }) {
  const { signedIn } = useAuth();

  return (
    <nav className="nav">
      <div className="nav-inner">
        <div
          className="wordmark"
          style={{ cursor: 'pointer' }}
          onClick={() => navigate('home')}
        >
          <svg className="wm-icon" viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
            <path d="M3 17 L9 11 L13 14 L21 6" />
            <path d="M15 6 H21 V12" />
          </svg>
          <span className="dot" />
          <span>CloudLayer</span>
          <span className="mono faint" style={{ fontSize: 10.5, letterSpacing: '0.08em', marginLeft: 6, transform: 'translateY(-1px)' }}>
            v1.0
          </span>
        </div>

        <div className="nav-links">
          <button className={`nav-link ${route.page === 'home' ? 'active' : ''}`} onClick={() => navigate('home')}>
            Benchmark
          </button>
          <button className={`nav-link ${route.page === 'toppicks' ? 'active' : ''}`} onClick={() => navigate('toppicks')}>
            Top picks
          </button>
          <CategoryDropdown
            navigate={navigate}
            currentCategory={route.page === 'category' ? route.params.slug : null}
          />
          <button className={`nav-link ${route.page === 'leaderboard' ? 'active' : ''}`} onClick={() => navigate('leaderboard')}>
            Leaderboard
          </button>
          <button className={`nav-link ${route.page === 'profile' ? 'active' : ''}`} onClick={() => navigate('profile')}>
            Track
          </button>
          <button className={`nav-link ${route.page === 'suggest' ? 'active' : ''}`} onClick={() => navigate('suggest')}>
            Suggest
          </button>
          <button className={`nav-link ${route.page === 'share' ? 'active' : ''}`} onClick={() => navigate('share')}>
            Share
          </button>
        </div>

        <div className="nav-right">
          {signedIn ? (
            <>
              <button className="btn btn-accent" onClick={() => navigate('profile')}>
                Track a prompt
              </button>
              <UserMenu navigate={navigate} />
            </>
          ) : (
            <SignInButton />
          )}
        </div>
      </div>
    </nav>
  );
}

// ── App ────────────────────────────────────────────────────────────────────
// ── Error boundary ────────────────────────────────────────────────────────
// React 18 unmounts the whole tree on an uncaught render error — which is
// what you see as a completely blank page. This boundary catches the throw
// so the nav stays visible and the user has a way out.
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { error: null };
  }
  static getDerivedStateFromError(error) {
    return { error };
  }
  componentDidCatch(error, info) {
    console.error('[ErrorBoundary]', error, info);
    // Best-effort: ping the server log too. Don't await.
    try {
      fetch('/api/errors', {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify({
          source: 'client:render',
          message: String(error?.message || error),
          stack: String(error?.stack || ''),
          path: window.location.pathname,
        }),
      }).catch(() => {});
    } catch {}
  }
  reset = () => this.setState({ error: null });
  render() {
    if (!this.state.error) return this.props.children;
    return (
      <div className="container" style={{ padding: '80px 32px', maxWidth: 720 }}>
        <h1 style={{ fontFamily: 'var(--ff-display)', fontSize: 48, fontWeight: 300, margin: 0 }}>
          Something broke <em style={{ color: 'var(--neg)' }}>here</em>.
        </h1>
        <div className="dim" style={{ marginTop: 16, fontSize: 14, lineHeight: 1.6 }}>
          A render error stopped this page from drawing. The rest of the app still works — try a different route or reload.
        </div>
        <pre style={{
          marginTop: 18, padding: 18, background: '#0a0b0e', border: '1px solid var(--border)',
          borderRadius: 4, fontFamily: 'var(--ff-mono)', fontSize: 12, color: 'var(--fg-dim)',
          whiteSpace: 'pre-wrap', maxHeight: 260, overflow: 'auto',
        }}>
{String(this.state.error?.stack || this.state.error?.message || this.state.error)}
        </pre>
        <div className="row gap-12" style={{ marginTop: 18 }}>
          <button className="btn" onClick={this.reset}>Try again</button>
          <button className="btn btn-accent" onClick={() => { window.history.pushState({}, '', '/'); window.dispatchEvent(new PopStateEvent('popstate')); this.reset(); }}>Go to benchmark</button>
        </div>
      </div>
    );
  }
}

function App() {
  const { route, navigate } = useRoute();
  // History-API mode — nothing to bootstrap; the initial pathname IS the route.

  // Re-key the boundary on route change so navigating away from a broken page
  // resets the error state.
  const boundaryKey = `${route.page}:${route.params.slug || route.params.id || ''}`;

  return (
    <>
      <Nav route={route} navigate={navigate} />
      <ErrorBoundary key={boundaryKey}>
        {route.page === 'home'        && <HomePage navigate={navigate} />}
        {route.page === 'toppicks'    && <TopPicksPage navigate={navigate} />}
        {route.page === 'category'    && <CategoryPage navigate={navigate} slug={route.params.slug} />}
        {route.page === 'market'      && <MarketPage navigate={navigate} polymarketId={route.params.id} />}
        {route.page === 'leaderboard' && <LeaderboardPage navigate={navigate} />}
        {route.page === 'profile'     && <ProfilePage navigate={navigate} />}
        {route.page === 'suggest'     && <SuggestPage navigate={navigate} />}
        {route.page === 'upgrade'     && <UpgradePage navigate={navigate} />}
        {route.page === 'share'       && <SharePage navigate={navigate} polymarketId={route.params.id} />}
      </ErrorBoundary>
    </>
  );
}

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