/**
 * dashboard/Dashboard.jsx — public face of the dashboard module.
 *
 * Renders the DOM structure the Three.js modules expect (#pool-stats,
 * #tx-log, app cards, SVG leader layer), then mounts the WebGPU scene
 * via init.js into the canvas-host div. All Three.js code lives in
 * init.js + ./modules/* — this file only owns the React lifecycle.
 *
 * No-bundler form:
 * - React is a window global (UMD via unpkg).
 * - dashboard/styles.css is loaded as a <link> in index.html, NOT
 *   imported here.
 * - dashboard/init.js is loaded as a <script type="module"> earlier
 *   in index.html and exposes initDashboard via window.initDashboard.
 * - This file is loaded as <script type="text/babel">.
 */
const { useEffect, useRef, useState } = React;

function Dashboard() {
  const containerRef = useRef(null)
  const [ready, setReady] = useState(false)

  useEffect(() => {
    // ES modules cache forever within a page load. The dashboard modules
    // capture DOM refs at top-level (e.g. document.getElementById('tx-log__list')).
    // If this component remounts after an in-SPA navigation, those cached refs
    // point to torn-down nodes and the panels stay empty. Force a fresh page
    // load on remount so module evaluation runs again with the current DOM.
    if (window.__strk20DashboardLoaded) {
      window.location.reload()
      return
    }
    window.__strk20DashboardLoaded = true

    let cleanupFn = null
    let cancelled = false
    // window.initDashboard is set by dashboard/init.js (loaded
    // earlier as a <script type="module"> in index.html).
    Promise.resolve(window.initDashboard).then((initDashboard) => {
      if (cancelled || !containerRef.current || !initDashboard) return
      initDashboard(containerRef.current).then((cleanup) => {
        if (cancelled) { cleanup?.(); return }
        cleanupFn = cleanup
        // Two rAFs so the first paint of the canvas + panels is committed
        // before we trigger the opacity transition — avoids a frame where
        // the fade-in starts on a still-empty scene.
        requestAnimationFrame(() => {
          requestAnimationFrame(() => setReady(true))
        })
      }).catch((err) => {
        console.error('Dashboard init failed:', err)
        setReady(true)
      })
    })
    return () => {
      cancelled = true
      cleanupFn?.()
    }
  }, [])

  return (
    <div className={`dashboard-root ${ready ? 'is-ready' : ''}`}>
      {/* The whole dashboard view (sphere, panels, app cards, leaders, the
          Go-to-data button) lives in one stage so it can slide UP as a unit
          when the DATA section opens — #data-section (a sibling below) slides
          up from below in lockstep, reading as a scroll-down. See
          .dashboard-stage in styles.css + datasection.js. */}
      <div className="dashboard-stage">
      <div ref={containerRef} className="dashboard-canvas-host" />

      <aside id="pool-stats" aria-label="STRK20 privacy pool state">
        <header id="pool-stats__head">
          <h3>STRK20 // POOL STATE</h3>
          <span className="live">LIVE</span>
        </header>
        {/* Values are honest placeholders: poolstats.js hydrates them
            instantly from the localStorage cache of the last live fetch,
            then keeps them fresh from the API. Hardcoded numbers here
            looked plausible and went stale (the "$11,748 bug"). */}
        <div className="frame">
          <div className="frame__label">CURRENT TVL</div>
          {/* The TVL/revenue charts now live in the dedicated DATA section
              (datasection.js), reached via "Go to data" — the old inline
              chart button next to this figure was removed. */}
          <div className="frame__row">
            <div className="frame__value" id="m-tvl">—</div>
          </div>
          <div className="frame__hint">USD · shielded across all tokens</div>
        </div>

        <div className="metrics">
          <div className="metric">
            <span className="metric__label">revenue</span>
            <span className="metric__value" id="m-revenue">—</span>
          </div>
          <div className="metric">
            <span className="metric__label">volume processed</span>
            <span className="metric__value" id="m-volume">—</span>
          </div>
          <div className="metric">
            <span className="metric__label">private tx cost</span>
            <span className="metric__value" id="m-txcost">4 STRK</span>
          </div>
          <div className="metric">
            <span className="metric__label">distinct users</span>
            <span className="metric__value" id="m-users">—</span>
          </div>
          <div className="activities-section__head">
            <span className="activities-section__head-title">most frequent activities</span>
            <span className="activities-section__head-window">30D</span>
          </div>
          <div id="activities-list" className="activities-list"></div>

          <div className="pool-stats-grid__title">all-time</div>
          <div className="pool-stats-grid">
            {/* Top row is LIVE (poolstats.js ← /agg/lifetime-conversions):
                swap/stake volumes = USD out-leg of classified in-pool
                round-trips. Bottom row needs per-protocol decoding and
                keeps its coming-soon tags. */}
            <div className="stat-cell">
              <div className="stat-cell__label">VOLUME SWAPPED</div>
              <div className="stat-cell__value" id="m-swapped">—</div>
            </div>
            <div className="stat-cell">
              <div className="stat-cell__label">PRIVATE STAKING</div>
              <div className="stat-cell__value" id="m-staking">—</div>
            </div>
            <div className="stat-cell" data-status="coming-soon">
              <div className="stat-cell__label">LENDING VOLUME</div>
              <div className="stat-cell__value" id="m-lending">$0</div>
            </div>
            <div className="stat-cell" data-status="coming-soon">
              <div className="stat-cell__label">BORROWING VOLUME</div>
              <div className="stat-cell__value" id="m-borrowing">$0</div>
            </div>
          </div>

          <div className="erc20-section__head">all shielded ERC20s</div>
          <div id="erc20-list" className="erc20-list"></div>
        </div>
      </aside>

      {/* Live app cards (Vesu / AVNU / Endur / Troves) placed around the
          sphere — positionCardsAroundSphere() in appdropdown.js anchors
          each at its CARD_PLACEMENT bearing just outside the sphere's
          screen circle, with kinked leader lines (#app-leaders below)
          tying each card to a point on the surface. applivevolume.js
          fills the public TVL/volume figures. Vesu replaced the old
          Ekubo card — Ekubo has no entry in the applivevolume APPS
          list, Vesu does (DefiLlama TVL + own API). */}
      <a className="app-card" data-app="vesu" data-position="nw"
         href="https://vesu.xyz" target="_blank" rel="noopener noreferrer"
         onClick={(e) => e.preventDefault()}>
        <div className="app-card__name">Vesu</div>
        <div className="app-card__head">
          <span className="app-card__tagline">Lending</span>
          <span className="app-card__metric-label">TVL</span>
        </div>
        <div className="app-card__logo-wrap">
          <img className="app-card__logo" src="/dashboard-assets/logos/vesu.png" alt="Vesu logo"
               onError={(e) => { e.currentTarget.style.display = 'none' }} />
        </div>
        <div className="app-card__values">
          <div className="app-card__row">
            <span className="app-card__vol-key">public:</span>
            <span className="app-card__vol-val" data-vol="pub">$…</span>
          </div>
          <div className="app-card__row">
            <span className="app-card__vol-key">private:</span>
            <span className="app-card__vol-val app-card__vol-pri">coming soon</span>
          </div>
        </div>
      </a>
      <a className="app-card" data-app="avnu" data-position="ne"
         href="https://avnu.fi" target="_blank" rel="noopener noreferrer"
         onClick={(e) => e.preventDefault()}>
        <div className="app-card__name">AVNU</div>
        <div className="app-card__head">
          <span className="app-card__tagline">DEX</span>
          <span className="app-card__metric-label">vol. 30D</span>
        </div>
        <div className="app-card__logo-wrap">
          <img className="app-card__logo" src="/dashboard-assets/logos/avnu.png" alt="AVNU logo" />
        </div>
        <div className="app-card__values">
          <div className="app-card__row">
            <span className="app-card__vol-key">public:</span>
            <span className="app-card__vol-val" data-vol="pub">$…</span>
          </div>
          <div className="app-card__row">
            <span className="app-card__vol-key">private:</span>
            <span className="app-card__vol-val app-card__vol-pri">coming soon</span>
          </div>
        </div>
      </a>
      <a className="app-card" data-app="endur" data-position="sw"
         href="https://endur.fi" target="_blank" rel="noopener noreferrer"
         onClick={(e) => e.preventDefault()}>
        <div className="app-card__name">Endur</div>
        <div className="app-card__head">
          <span className="app-card__tagline">Staking & LSTs</span>
          <span className="app-card__metric-label">TVL</span>
        </div>
        <div className="app-card__logo-wrap">
          <img className="app-card__logo" src="/dashboard-assets/logos/endur.png" alt="Endur logo" />
        </div>
        <div className="app-card__values">
          <div className="app-card__row">
            <span className="app-card__vol-key">public:</span>
            <span className="app-card__vol-val" data-vol="pub">$…</span>
          </div>
          <div className="app-card__row">
            <span className="app-card__vol-key">private:</span>
            <span className="app-card__vol-val app-card__vol-pri">coming soon</span>
          </div>
        </div>
      </a>
      <a className="app-card" data-app="troves" data-position="se"
         href="https://troves.fi" target="_blank" rel="noopener noreferrer"
         onClick={(e) => e.preventDefault()}>
        <div className="app-card__name">Troves</div>
        <div className="app-card__head">
          <span className="app-card__tagline">Yield strategies</span>
          <span className="app-card__metric-label">TVL</span>
        </div>
        <div className="app-card__logo-wrap">
          <img className="app-card__logo" src="/dashboard-assets/logos/troves.png" alt="Troves logo" />
        </div>
        <div className="app-card__values">
          <div className="app-card__row">
            <span className="app-card__vol-key">public:</span>
            <span className="app-card__vol-val" data-vol="pub">$…</span>
          </div>
          <div className="app-card__row">
            <span className="app-card__vol-key">private:</span>
            <span className="app-card__vol-val app-card__vol-pri">coming soon</span>
          </div>
        </div>
      </a>

      <svg id="app-leaders" aria-hidden="true">
        <defs>
          <linearGradient id="leader-multicolor"
                          x1="0" y1="0" x2="48" y2="0"
                          gradientUnits="userSpaceOnUse"
                          spreadMethod="repeat">
            <stop offset="0%" stopColor="#ffe34d" />
            <stop offset="20%" stopColor="#ff5b3c" />
            <stop offset="40%" stopColor="#ffaa40" />
            <stop offset="60%" stopColor="#80ff80" />
            <stop offset="80%" stopColor="#40e0d0" />
            <stop offset="100%" stopColor="#ffe34d" />
            <animateTransform attributeName="gradientTransform"
                              type="translate"
                              from="0 0" to="48 0"
                              dur="2.4s"
                              repeatCount="indefinite" />
          </linearGradient>
        </defs>
        {/* Live-app leaders: solid grey outer line + animated multicolor
            inner segment + bright orange dot at the sphere endpoint. */}
        {['vesu', 'avnu', 'endur', 'troves'].map((app) => (
          <polyline key={`out-${app}`} data-leader-out={app} stroke="#9893a8" strokeWidth="1.6" fill="none" strokeLinejoin="miter" />
        ))}
        {['vesu', 'avnu', 'endur', 'troves'].map((app) => (
          <polyline key={`in-${app}`} data-leader-in={app} stroke="url(#leader-multicolor)" strokeWidth="2" fill="none" strokeLinejoin="miter" />
        ))}
        {['vesu', 'avnu', 'endur', 'troves'].map((app) => (
          <circle key={`dot-${app}`} data-leader-dot={app} r="2.5" fill="#e86a2d" cx="0" cy="0" />
        ))}
      </svg>

      <aside id="tx-log" aria-label="Privacy pool live transactions">
        <header id="tx-log__head">
          <span>STRK20 // LIVE TX</span>
          <span className="live">REC</span>
        </header>
        <div id="tx-log__list"></div>
        <footer id="tx-log__foot">
          <div className="tx-log__foot-label">UPTIME</div>
          <div className="tx-log__foot-row">
            <div className="tx-log__foot-col">
              <div id="uptime-chart" className="tx-log__foot-chart" aria-hidden="true"></div>
              <div className="tx-log__foot-ticks">
                <span>90D ago</span>
                <span>Today</span>
              </div>
            </div>
            <div id="uptime-pct" className="tx-log__foot-pct">100<sup>%</sup></div>
          </div>
        </footer>
      </aside>

      {/* Slides up the data section (datasection.js). The dashboard is a
          fixed full-viewport 3D scene with the wheel hijacked to rotate the
          sphere (init.js), so there's no document scroll to a section below
          — this button drives the transition instead. */}
      <button id="go-to-data" className="go-to-data" aria-label="Go to the live charts">
        <span>Go to live charts</span>
        <svg viewBox="0 0 16 16" width="13" height="13" aria-hidden="true">
          <polyline points="3,6 8,11 13,6" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" />
        </svg>
      </button>
      </div>{/* /.dashboard-stage */}

      {/* Dedicated charts surface. Slides up FROM BELOW in lockstep with the
          dashboard stage sliding up — together they read as a scroll-down.
          A sibling of .dashboard-stage (not inside it) so it stays fixed to
          the viewport and moves independently. TVL (left) + Revenue (right),
          drawn with the same liveline engine the TVL drawer uses. */}
      <section id="data-section" aria-label="STRK20 TVL and revenue charts">
        <header className="data-section__head">
          <button id="back-to-dashboard" className="data-section__back" aria-label="Back to dashboard">
            <span>Back to dashboard</span>
            <svg viewBox="0 0 16 16" width="13" height="13" aria-hidden="true">
              <polyline points="3,10 8,5 13,10" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
          </button>
          <span className="data-section__title">STRK20 // LIVE CHARTS</span>
        </header>
        <div className="data-section__grid">
          <div className="data-chart">
            <div className="data-chart__label">TVL<span className="data-chart__unit">USD · shielded across all tokens</span></div>
            <div id="data-tvl-chart" className="data-chart__canvas"></div>
          </div>
          <div className="data-chart">
            <div className="data-chart__label">Revenue<span className="data-chart__unit">protocol fees · cumulative + daily</span></div>
            <div id="data-revenue-chart" className="data-chart__canvas"></div>
          </div>
          <div className="data-chart">
            <div className="data-chart__label">Private Swap Volume<span className="data-chart__unit">by token · last 30d, USD</span></div>
            <div id="data-swap-legend" className="data-volume-legend" aria-hidden="true"></div>
            <div id="data-swap-chart" className="data-chart__canvas"></div>
          </div>
          <div className="data-chart">
            <div className="data-chart__label">DeFi Volume<span className="data-chart__unit">privately routed · by protocol · last 30d</span></div>
            <div id="data-volume-legend" className="data-volume-legend" aria-hidden="true"></div>
            <div id="data-volume-chart" className="data-chart__canvas"></div>
          </div>
          <div className="data-chart">
            <div className="data-chart__label">Shielded Balance<span className="data-chart__unit">by token · last 30d, USD</span></div>
            <div id="data-shielded-legend" className="data-volume-legend" aria-hidden="true"></div>
            <div id="data-shielded-chart" className="data-chart__canvas"></div>
          </div>
          <div className="data-chart">
            <div className="data-chart__label">Transactions<span className="data-chart__unit">count · daily</span></div>
            <div id="data-tx-chart" className="data-chart__canvas"></div>
          </div>
          <div className="data-chart data-chart--wide">
            <div className="data-chart__label">New Users<span className="data-chart__unit">viewing-key registrations · cumulative + daily</span></div>
            <div id="data-newusers-chart" className="data-chart__canvas"></div>
          </div>
        </div>
      </section>
    </div>
  )
}

// No export — loaded as a script tag, Dashboard becomes a window
// global referenced by app.jsx's pathname switch.
