/* HLP composition tooling — main app.
   Tabs: Composition · PnL by tier · Asset breakdown.
   Cascade window marked on time-series only.
*/
const { useState, useEffect, useMemo } = React;

function Header() {
  const s = D.summary;
  return (
    <header className="header">
      <div>
        <h1>HLP Composition · PnL Atlas</h1>
        <div className="smallcaps" style={{ marginTop: 4, color: 'var(--ink-3)' }}>
          {s.data_coverage.start} → {s.data_coverage.end} · {s.data_coverage.days} days · {D.vaults.length} vaults · {D.assets.length} assets
        </div>
      </div>
      <div className="meta">As of {s.data_coverage.end}</div>
    </header>
  );
}

function GlobalDisclaimer() {
  return (
    <div className="panel-note global-note">
      <div className="note-row">
        <span className="nlabel">Oct 10–11 caveat</span>
        <span>Cascade-window figures are preliminary pending HyperCore precompile-state confirmation from a validator. All time-series flag those days.</span>
      </div>
      <div className="note-row">
        <span className="nlabel">Tier classification</span>
        <span>Tiers are <em>static</em> across the window — coins that moved tiers (e.g. PUMP from meme to mid-cap) are bucketed by their current designation only.</span>
      </div>
    </div>
  );
}

function KPIs() {
  const totals = D.assetTotals;
  const totalPnL = totals.reduce((s, r) => s + r.total, 0);
  const winners = totals.filter(r => r.total > 0);
  const losers = totals.filter(r => r.total < 0);
  const totalAVNow = D.summary.total_av_latest;
  const totalAVStart = D.summary.total_av_start;
  const avDelta = ((totalAVNow - totalAVStart) / totalAVStart) * 100;

  return (
    <div className="kpis">
      <div className="kpi">
        <div className="k-label">Total HLP AV</div>
        <div className="k-val mono">{fmtUSD(totalAVNow)}</div>
        <div className="k-sub">{avDelta >= 0 ? '+' : '−'}{Math.abs(avDelta).toFixed(1)}% since {D.summary.data_coverage.start.slice(0,7)}</div>
      </div>
      <div className="kpi">
        <div className="k-label">Cumulative perp PnL</div>
        <div className="k-val mono" style={{ color: totalPnL >= 0 ? 'var(--gain)' : 'var(--loss)' }}>{fmtPnL(totalPnL)}</div>
        <div className="k-sub">{D.summary.data_coverage.days} days, all sub-vaults</div>
      </div>
      <div className="kpi">
        <div className="k-label">Winners / losers</div>
        <div className="k-val mono">{winners.length}<span style={{ color: 'var(--ink-3)' }}> / </span>{losers.length}</div>
        <div className="k-sub">of {totals.length} tracked assets</div>
      </div>
      <div className="kpi">
        <div className="k-label">Top contributor</div>
        <div className="k-val mono">{totals[0].sym}</div>
        <div className={`k-sub ${totals[0].total >= 0 ? 'gain' : 'loss'}`}>{fmtPnL(totals[0].total)}</div>
      </div>
    </div>
  );
}

function CompositionPanel() {
  const [vault, setVault] = useState('TOTAL');
  const [mode, setMode] = useState('absolute');
  const vaultOptions = ['TOTAL', ...D.vaults.filter(v => v !== 'HLP (parent)')];

  return (
    <section className="panel">
      <div className="panel-head">
        <h2>Vault composition over time</h2>
      </div>
      <div className="filter-strip">
        <span className="smallcaps" style={{ marginRight: 8 }}>Vault</span>
        {vaultOptions.map(v => (
          <button key={v} className={`filter-chip ${vault === v ? 'is-active' : ''}`} onClick={() => setVault(v)}>
            {v === 'TOTAL' ? 'All sub-vaults' : v}
          </button>
        ))}
        <span style={{ width: 16 }} />
        <span className="smallcaps" style={{ marginRight: 8 }}>Scale</span>
        <button className={`filter-chip ${mode === 'absolute' ? 'is-active' : ''}`} onClick={() => setMode('absolute')}>USD</button>
        <button className={`filter-chip ${mode === 'percent' ? 'is-active' : ''}`} onClick={() => setMode('percent')}>% of AV</button>
      </div>
      <CompositionChart vault={vault} mode={mode} height={340} />
    </section>
  );
}

function SharePanel() {
  const tiers = ['major', 'mid', 'longtail', 'meme'];
  const [view, setView] = useState('overview');

  return (
    <section className="panel">
      <div className="panel-head">
        <h2>HLP share of Hyperliquid fill volume</h2>
        <div className="panel-kicker">
          {view === 'overview'
            ? 'Per-coin median (left axis, ~50%) vs volume-weighted system share (right axis, ~2%)'
            : 'Tier mean + min/max range, daily · drill-down by asset tier'}
        </div>
      </div>
      <div className="filter-strip">
        <span className="smallcaps" style={{ marginRight: 8 }}>View</span>
        <button className={`filter-chip ${view === 'overview' ? 'is-active' : ''}`} onClick={() => setView('overview')}>System overview</button>
        <button className={`filter-chip ${view === 'tier' ? 'is-active' : ''}`} onClick={() => setView('tier')}>By tier</button>
      </div>
      <div className="panel-note">
        <span className="nlabel">HL volume scope</span>
        <span>{D.bcPerpsNote || 'Volume denominators cover crypto perps only; Builder Code (TradFi) markets excluded.'}</span>
      </div>
      {view === 'overview'
        ? <HLPShareHeadlineChart height={360} />
        : (
          <div className="share-grid">
            {tiers.map(t => <ShareTierChart key={t} tier={t} metric="volume" height={220} />)}
          </div>
        )}
    </section>
  );
}

function UtilizationPanel() {
  return (
    <section className="panel panel-headline">
      <div className="panel-head">
        <h2>Strategy A/B utilization</h2>
        <div className="panel-kicker">Daily combined TVL (left) vs utilization = volume ÷ TVL (right)</div>
      </div>
      <div className="panel-note">
        <span className="nlabel">Hydromancer gap</span>
        <span>No Hydromancer snapshots {D.hydromancerGap?.start} → {D.hydromancerGap?.end}. TVL is anchored to four vault_pnl weekly account_value points (Oct 29, Nov 12, Nov 26, Dec 10) and linearly interpolated between them — rendered dashed with anchor circles.</span>
      </div>
      <UtilizationChart height={360} />
    </section>
  );
}

function CascadePhasesPanel() {
  return (
    <section className="panel">
      <div className="panel-head">
        <h2>Multi-stage cascade response</h2>
        <div className="panel-kicker">Five phases · HLP daily volume vs non-HLP long-tail participant counts</div>
      </div>
      <div className="panel-note">
        <span className="nlabel">HL volume scope</span>
        <span>{D.bcPerpsNote || 'Volume denominators cover crypto perps only; Builder Code (TradFi) markets excluded.'}</span>
      </div>
      <CascadePhasesChart height={300} />
    </section>
  );
}

function AssetPnLPanel() {
  const [scope, setScope] = useState('top');
  const [tier, setTier] = useState('all');
  const [topN, setTopN] = useState(8);

  return (
    <section className="panel">
      <div className="panel-head">
        <h2>PnL by asset over time</h2>
        <div className="panel-kicker">Cumulative · top {topN} {scope === 'top' ? 'movers' : scope} · {tier === 'all' ? 'all tiers' : TIER_LABEL[tier]}</div>
      </div>
      <div className="filter-strip">
        <span className="smallcaps" style={{ marginRight: 8 }}>Show</span>
        <button className={`filter-chip ${scope === 'top' ? 'is-active' : ''}`} onClick={() => setScope('top')}>Top movers</button>
        <button className={`filter-chip ${scope === 'gainers' ? 'is-active' : ''}`} onClick={() => setScope('gainers')}>Gainers</button>
        <button className={`filter-chip ${scope === 'losers' ? 'is-active' : ''}`} onClick={() => setScope('losers')}>Losers</button>
        <span style={{ width: 16 }} />
        <span className="smallcaps" style={{ marginRight: 8 }}>Tier</span>
        {['all', 'major', 'mid', 'longtail', 'meme'].map(t => (
          <button key={t} className={`filter-chip ${tier === t ? 'is-active' : ''}`} onClick={() => setTier(t)}>
            {t === 'all' ? 'All' : TIER_LABEL[t]}
          </button>
        ))}
        <span style={{ width: 16 }} />
        <span className="smallcaps" style={{ marginRight: 8 }}>Count</span>
        {[5, 10, 20, 50, 100].map(n => (
          <button key={n} className={`filter-chip ${topN === n ? 'is-active' : ''}`} onClick={() => setTopN(n)}>{n}</button>
        ))}
      </div>
      <CumulativeAssetPnL scope={scope} tierFilter={tier} topN={topN} height={360} />
    </section>
  );
}

function PnLPanel() {
  return (
    <section className="panel">
      <div className="panel-head">
        <h2>Cumulative PnL by asset tier</h2>
        <div className="panel-kicker">All sub-vaults · Oct 10–11 + Jan 31–Feb 1 marked</div>
      </div>
      <CumulativeTierPnL height={340} />
    </section>
  );
}

function LeaderboardPanel() {
  const [tier, setTier] = useState('all');
  return (
    <section className="panel">
      <div className="panel-head">
        <h2>Asset leaderboard</h2>
        <div className="panel-kicker">Cumulative PnL · all sub-vaults · {D.summary.data_coverage.days}-day window</div>
      </div>
      <div className="filter-strip">
        <span className="smallcaps" style={{ marginRight: 8 }}>Tier</span>
        {['all', 'major', 'mid', 'longtail', 'meme'].map(t => (
          <button key={t} className={`filter-chip ${tier === t ? 'is-active' : ''}`} onClick={() => setTier(t)}>
            {t === 'all' ? 'All assets' : TIER_LABEL[t]}
          </button>
        ))}
      </div>
      <AssetLeaderboard tier={tier} />
    </section>
  );
}

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "density": "comfortable",
  "serif": "sourceserif"
}/*EDITMODE-END*/;

function App() {
  const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS);

  useEffect(() => {
    document.documentElement.dataset.density = tweaks.density;
    document.documentElement.dataset.serif = tweaks.serif;
  }, [tweaks]);

  return (
    <div className="page">
      <Header />
      <GlobalDisclaimer />
      <KPIs />
      <CompositionPanel />
      <PnLPanel />
      <AssetPnLPanel />
      <UtilizationPanel />
      <SharePanel />
      <CascadePhasesPanel />
      <LeaderboardPanel />

      <TweaksPanel title="Tweaks">
        <TweakSection title="Display">
          <TweakRadio
            label="Density"
            value={tweaks.density}
            options={[
              { value: 'comfortable', label: 'Comfortable' },
              { value: 'compact', label: 'Compact' },
            ]}
            onChange={(v) => setTweak('density', v)}
          />
          <TweakSelect
            label="Serif family"
            value={tweaks.serif}
            options={[
              { value: 'sourceserif', label: 'Source Serif 4' },
              { value: 'newsreader', label: 'Newsreader' },
              { value: 'fraunces', label: 'Fraunces' },
              { value: 'spectral', label: 'Spectral' },
              { value: 'ebgaramond', label: 'EB Garamond' },
            ]}
            onChange={(v) => setTweak('serif', v)}
          />
        </TweakSection>
      </TweaksPanel>
    </div>
  );
}

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