// ============================================================
// 18% CLUB · FULL PERFORMANCE DASHBOARD
// dashboard.jsx — secondary page linked from the Trade Desk homepage.
// Mirrors the existing local "nq-trading-dashboard" artifact
// (Projects/02_Order Executor/dashboard/trading_dashboard.html).
// ============================================================

const { useEffect: dbUseEffect, useState: dbUseState, useMemo: dbUseMemo } = React;

// Format an ISO timestamp as its US Eastern calendar date (e.g. "30 May 2026"),
// regardless of the timestamp's own offset or the viewer's locale. All public
// dates on the site are anchored to ET (the market's timezone).
function fmtETDate(iso) {
  if (!iso) return '';
  const et = new Date(iso).toLocaleDateString('en-CA', { timeZone: 'America/New_York' }); // YYYY-MM-DD
  return fmtHuman(et);
}

// Where "back" goes depends on how the user arrived: the mobile site and the
// desktop index are two distinct experiences. Prefer an explicit ?from= flag
// (set on every inbound link), fall back to the referrer, default to index.
function resolveBack() {
  try {
    const from = new URLSearchParams(location.search).get('from');
    if (from === 'mobile') return { href: 'mobile.html', label: 'Mobile' };
    if (from === 'index') return { href: 'index.html', label: 'Trade Desk' };
    if (/\/mobile\.html(\?|#|$)/.test(document.referrer || '')) return { href: 'mobile.html', label: 'Mobile' };
  } catch (_) {}
  return { href: 'index.html', label: 'Trade Desk' };
}
const BACK = resolveBack();

// ---------- Dashboard nav (with back link) ----------
function DashNav({ tradingDay, publishedAt, schemaVersion, rulebookVersion }) {
  return (
      <div className="nav">
        <a className="logo" href={BACK.href} aria-label={`Back to ${BACK.label}`}>
          <img className="logo-mark" src={window.__resources && window.__resources.logo || "assets/logo/18club-logo.png"} alt="18% Club" width="40" height="40" />
          <span className="logo-wm">
            <span className="wm-main">18% Club</span>
            <span className="wm-sub">trade desk</span>
          </span>
        </a>
        <nav className="nav-links" aria-label="Primary">
          <a className="nav-link" href="index.html">Trade Desk</a>
          <a className="nav-link active" href="dashboard.html">Performance Dashboard</a>
          <a className="nav-link" href="structural-bias.html">Structural Bias</a>
          <a className="nav-link" href="market-sensing.html">Market Sensing</a>
          <a className="nav-link" href="rulebook.html">Rulebook</a>
          <a className="nav-link" href="indicator.html">Indicator</a>
        </nav>
        <a className="nav-discord" href="https://discord.gg/sbpjpCBbFv" target="_blank" rel="noopener noreferrer">
          <div className="nav-discord-copy">
            <span className="nav-discord-eb">in the discord · live</span>
            <span className="nav-discord-h">Today · <em>running live</em></span>
          </div>
          <span className="nav-discord-btn">Join Free →</span>
        </a>
      </div>
  );
}

// ---------- Per-tier breakdown (stub of trading_dashboard.html section) ----------
function TierBreakdown({ trades, kpis }) {
  // Derive simple per-tier stats from the trades array
  const tiers = dbUseMemo(() => {
    const groups = {};
    trades.forEach((t) => {
      const k = t.tier || 'tier-?';
      if (!groups[k]) groups[k] = { wins: 0, losses: 0, open: 0, pnl: 0 };
      if (t.result === 'win') {groups[k].wins++;groups[k].pnl += t.realized_pnl_usd || 0;} else
      if (t.result === 'loss') {groups[k].losses++;groups[k].pnl += t.realized_pnl_usd || 0;} else
      {groups[k].open++;groups[k].pnl += t.unrealized_pnl_usd || 0;}
    });
    return groups;
  }, [trades]);

  const keys = Object.keys(tiers);

  return (
    <div className="stat-sheet" style={{ marginBottom: 12 }}>
      <div className="stat-h">
        <span className="stat-t">Per-tier breakdown</span>
        <span className="stat-m">SHOWN: TRADES IN THE 30D SAMPLE</span>
      </div>
      <div className="stat-grid">
        {keys.map((k) => {
          const g = tiers[k];
          const total = g.wins + g.losses;
          const wr = total ? g.wins / total : 0;
          return (
            <div key={k} className="stat-row" style={{ borderBottom: '1px dashed var(--border)', padding: '10px 0' }}>
              <span className="k">{k}</span>
              <span className="v">
                {g.wins}W / {g.losses}L · <b style={{ color: g.pnl >= 0 ? 'var(--pos)' : 'var(--neg)' }}>{g.pnl >= 0 ? '+' : '−'}${Math.abs(g.pnl).toLocaleString()}</b>
                <span style={{ color: 'var(--stone-1)', marginLeft: 6 }}>· {(wr * 100).toFixed(0)}% wr</span>
              </span>
            </div>);

        })}
      </div>
      <div className="coming-stub" style={{ marginTop: 10 }}>
        <div className="stub-eb">sample-only</div>
        <b>Per-tier section showing 5 trades from the 30-day window.</b> The production dashboard
        (in the local <code>02_Order Executor/dashboard/</code> folder) reads the full <code>trade_log.xlsx</code> and shows every tier-1 / tier-2 / aggressive trade across the entire account history. That richer version will land here once the daily assembly script ships.
      </div>
    </div>);

}

// ---------- Closed trades table ----------
function TradesTable({ trades }) {
  const closed = trades.filter((t) => t.result !== 'open');
  return (
    <div className="stat-sheet" style={{ marginBottom: 12 }}>
      <div className="stat-h">
        <span className="stat-t">Closed trades · last 30D sample</span>
        <span className="stat-m">{closed.length} SHOWN · TAP A ROW</span>
      </div>
      <div className="trades-table">
        <div className="tt-head">
          <span className="tt-c-date">Date</span>
          <span className="tt-c-dir">Dir</span>
          <span className="tt-c-tier">Tier</span>
          <span className="tt-c-entry">Entry</span>
          <span className="tt-c-exit">Exit</span>
          <span className="tt-c-pnl">P&L</span>
        </div>
        {closed.map((t) =>
        <a key={t.id} className={`tt-row ${t.result}`} href={`index.html#trade=${t.id}`}>
            <span className="tt-c-date">{fmtShort(t.date)}</span>
            <span className="tt-c-dir">{t.direction.charAt(0).toUpperCase()}</span>
            <span className="tt-c-tier">{t.tier.replace('tier-', 'T')}</span>
            <span className="tt-c-entry">{fmtPrice(t.entry_price)}</span>
            <span className="tt-c-exit">{fmtPrice(t.exit_price)}</span>
            <span className={`tt-c-pnl ${t.result}`}>{(t.realized_pnl_usd || 0) >= 0 ? '+' : '−'}${Math.abs(t.realized_pnl_usd || 0).toLocaleString()}</span>
          </a>
        )}
      </div>
    </div>);

}

// ---------- Dashboard root ----------
function Dashboard() {
  const [data, setData] = dbUseState(null);
  const [err, setErr] = dbUseState(null);
  const [range, setRange] = dbUseState('all');
  const [customStart, setCustomStart] = dbUseState('');

  dbUseEffect(() => {
    const R = window.__resources || {};
    const okJson = (label) => (r) => {if (!r.ok) throw new Error('Failed to load ' + label + ': ' + r.status);return r.json();};
    // Legacy single-file fallback (standalone bundle) when only tradeData is set.
    if (R.tradeData && !R.performance) {
      fetch(R.tradeData).then(okJson('trade data')).then(setData).catch((e) => {console.error(e);setErr(e.message);});
      return;
    }
    const perfUrl = R.performance || 'data/performance.json';
    const tradesUrl = R.trades || 'data/trades.json';
    Promise.all([
    fetch(perfUrl).then(okJson('performance.json')),
    fetch(tradesUrl).then(okJson('trades.json'))]).
    then(([perf, tr]) => {
      setData({
        ...perf,
        ...tr,
        meta: { ...(tr.meta || {}), ...(perf.meta || {}) },
        chart: { ...(perf.chart || {}), ...(tr.chart || {}) } });

    }).
    catch((e) => {console.error(e);setErr(e.message);});
  }, []);

  const flt = dbUseMemo(() => {
    if (!data) return null;
    const ohlc = data.chart.ohlc || [];
    const lastDate = (ohlc[ohlc.length - 1] || {}).date || data.meta.trading_day;
    const firstDate = (ohlc[0] || {}).date || '';
    let cutoff = null;
    if (customStart) cutoff = customStart;else
    if (range !== 'all') {
      const days = range === '30d' ? 30 : range === '14d' ? 14 : 7;
      // Parse the ISO date as UTC and read it back as UTC so the cutoff doesn't
      // shift by a day for viewers behind/ahead of UTC.
      const d = new Date(lastDate + 'T00:00:00Z');d.setUTCDate(d.getUTCDate() - days);
      cutoff = d.toISOString().slice(0, 10);
    }
    const keep = (iso) => !cutoff || iso && iso >= cutoff;
    return {
      cutoff, lastDate, firstDate,
      chart: Object.assign({}, data.chart, {
        ohlc: ohlc.filter((d) => keep(d.date)),
        marks: (data.chart.marks || []).filter((m) => keep(m.date))
      }),
      equity: (data.equity_curve || []).filter((p) => keep(p.date)),
      trades: (data.trades || []).filter((t) => keep(t.date))
    };
  }, [data, range, customStart]);

  if (err) {
    return (
      <div className="app">
        <div className="pad">
          <h2 className="hd-h">Couldn't load trade data.</h2>
          <p className="hd-l">{err}</p>
          <p><a href={BACK.href}>← Back to {BACK.label}</a></p>
        </div>
      </div>);

  }
  if (!data) {
    return (
      <div className="app">
        <div className="pad" style={{ textAlign: 'center', paddingTop: 80 }}>
          <div style={{ fontFamily: 'Georgia, serif', fontStyle: 'italic', color: '#917F6C' }}>Loading the dashboard…</div>
        </div>
      </div>);

  }

  return (
    <div className="app">
      <DashNav
        tradingDay={data.meta.trading_day}
        publishedAt={data.meta.published_at}
        schemaVersion={data.meta.schema_version}
        rulebookVersion={data.meta.rulebook_version} />
      

      <div className="pad">
        <a className="sb-back" href={BACK.href}><span className="arr">←</span> Back to {BACK.label}</a>
        <p className="hd-eb" style={{ fontSize: '13px', letterSpacing: '0.1em' }}>full performance report, since 22 Apr 2026</p>
        <h2 className="hd-h">One Asset, One System, <em>One Map</em></h2>

        <MissionStrip account={data.account} kpis={data.kpis} meta={data.meta} />

        <div className="dsh-kpis">
          <FullKpiGrid kpis={data.kpis} realized={data.realized_by_period} />
        </div>

        <FilterBar
          range={range}
          customStart={customStart}
          onRange={(k) => {setRange(k);setCustomStart('');}}
          onCustom={(v) => setCustomStart(v)}
          lastDate={flt.lastDate}
          firstDate={flt.firstDate} />

        <PriceChart chart={flt.chart} trades={flt.trades} />

        <div className="dsh-grid-2">
          <EquityChart equity={flt.equity} />
          <ReturnChart equity={flt.equity} account={data.account} />
        </div>

        <div className="dsh-grid-2">
          <TierChart trades={flt.trades} />
          <StatSheet kpis={data.kpis} />
        </div>

        <PlansTable trades={flt.trades} chart={flt.chart} />
      </div>

      <section className="chain-section" id="chain">
        <p className="hd-eb">the real moat</p>
        <h2 className="hd-h">A chain you can't fake.</h2>
        <p className="hd-l">Anyone can post a winning screenshot. Few can prove the chain.</p>
        <p className="hd-l">A single trade can be copied. A green P&amp;L can be staged. But an unbroken operating record cannot be faked easily: pre-market plans timestamped before price moves, trades reconciled to real fills, losses published, rules versioned, and every decision traced from raw data to result.</p>
        <ol className="chain-list">
          {[['01', 'Raw data'], ['02', 'Pre-market plan'], ['03', 'Timestamped decision'], ['04', 'Schedule & execute trade'], ['05', 'Broker confirmation'], ['06', 'Post-market review'], ['07', 'Rulebook upgrade']].map((n, i, arr) =>
          <li key={n[0]} className="chain-node">
              <div className="chain-num">{n[0]}</div>
              <div className="chain-body"><div className="chain-t">{n[1]}</div></div>
              {i < arr.length - 1 && <div className="chain-link" aria-hidden="true" />}
            </li>
          )}
        </ol>
      </section>

      <div className="footer footer-simple">
        <img
          className="footer-logo"
          src={window.__resources && window.__resources.logo || "assets/logo/18club-logo.png"}
          alt="18% Club"
          width="36"
          height="36" />
        <span className="footer-copy">© {data.meta.published_at.slice(0, 4)} 18% Club · All rights reserved. Education only — not financial advice. Operated from Singapore. Past performance is not indicative of future results.</span>
      </div>
    </div>);

}

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