/* ============================================================
   market-sensor.jsx — app shell. Pure renderer of data/pulse.json.
   Dark cool-slate band. 3 switchable State Hero treatments.
   Handles stale data, UNKNOWN, fetch error, empty catalysts.
   ============================================================ */
const { useState: useStateA, useEffect: useEffectA, useCallback: useCbA } = React;

/* QA aid: ?state=WHIPSAW overrides the live state for visual testing of all
   8 enum values. Harmless in production (only fires when the param is present). */
const MSR_DEFAULT_COLOR = {
  CONFIRMING: 'green', MILD_BULL: 'green', NEUTRAL: 'navy', MILD_BEAR: 'amber',
  WHIPSAW: 'amber', DIRECTIONAL_RISK: 'red', EVENT_RISK: 'purple', UNKNOWN: 'grey',
};
function msrApplyOverride(d) {
  try {
    const p = new URLSearchParams(location.search);
    const st = p.get('state');
    if (st && MSR_DEFAULT_COLOR[st] && d && d.state) {
      d.state = { ...d.state, label: st, color: MSR_DEFAULT_COLOR[st] };
    }
  } catch (e) {}
  return d;
}

function MsrNav() {
  return (
    <div className="msr-nav">
      <div className="msr-nav-in">
        <a className="msr-logo" href="index.html"><span style={{ fontFamily: 'var(--fdisp)', fontSize: 17, fontWeight: 700, letterSpacing: '-0.01em', color: 'var(--cream)', display: 'inline-flex', alignItems: 'center' }}><span style={{ fontWeight: 400 }}>Tank</span><span style={{ display: 'inline-block', width: 5, height: 5, borderRadius: '50%', background: 'var(--mustard)', margin: '0 5px' }} />TradingDesk</span></a>
        <nav className="msr-links">
          <a className="msr-link" href="index.html">Trade Desk</a>
          <a className="msr-link" href="track-records.html">Track Records</a>
          <a className="msr-link" href="dashboard.html?from=market-sensor">Performance Dashboard</a>
          <a className="msr-link" href="rulebook.html">Rulebook</a>
          <a className="msr-link" href="indicator.html">Indicator</a>
        </nav>
        <a className="msr-cta" href="https://discord.gg/sbpjpCBbFv" target="_blank" rel="noopener noreferrer">Join Discord →</a>
      </div>
    </div>
  );
}

function MsrApp() {
  const [data, setData] = useStateA(null);
  const [err, setErr] = useStateA(null);
  const [loading, setLoading] = useStateA(true);

  const load = useCbA(() => {
    setLoading(true); setErr(null);
    const R = window.__resources || {};
    const url = R.pulse || 'data/pulse.json';
    fetch(url, { cache: 'no-store' })
      .then((r) => { if (!r.ok) throw new Error('pulse.json ' + r.status); return r.json(); })
      .then((d) => { setData(msrApplyOverride(d)); setLoading(false); })
      .catch((e) => { setErr(e.message); setLoading(false); });
  }, []);
  useEffectA(() => { load(); }, [load]);

  if (loading && !data) return (
    <div className="msr"><MsrNav /><div className="msr-wrap"><div className="msr-load"><div className="l">Loading pre-market sensor…</div></div></div></div>
  );
  if (err && !data) return (
    <div className="msr"><MsrNav /><div className="msr-wrap"><div className="msr-err">
      <div className="l">Error</div><div className="h">Could not load the Market Sensor.</div>
      <div className="l">{err}</div><button className="msr-retry" onClick={load}>Retry</button>
    </div></div></div>
  );

  const s = data.state || {};
  const meta = data.meta || {};
  const stale = window.msrStale(meta);
  const unknown = s.label === 'UNKNOWN';
  const HeroRender = window.MSR_HEROES.B.render; /* locked: Action Console */

  return (
    <div className="msr">
      <MsrNav />
      <div className="msr-wrap">
        {stale.stale && (
          <div className="msr-stale"><span>{'\u26A0'}</span><span><span className="b">Last update was {stale.label}.</span> Data may be stale — the sensor runs ~T-45 before the U.S. open.</span>
            <button className="msr-retry" style={{ marginLeft: 'auto', padding: '7px 14px' }} onClick={load}>Refresh</button></div>
        )}

        <div className="msr-head">
          <h1 className="msr-title">Pre-market <em>volatility regime</em> sensor</h1>
        </div>

        {/* STATE HERO — Action Console */}
        {unknown
          ? <div className="msr-hero" style={{ ['--tone']: window.msrTone('grey') }}>
              <div className="msr-heroA-top"><span className="msr-chip lg" style={{ ['--tone']: window.msrTone('grey') }}><span className="gly">?</span>UNKNOWN</span></div>
              <p className="msr-heroA-msg">Sensor data is incomplete today. Refer to <a href="structural-bias.html" style={{ color: 'var(--mustard)' }}>Structural Bias</a> for direction.</p>
              <button className="msr-retry" onClick={load}>Retry</button>
            </div>
          : <HeroRender data={data} />}

        {/* [B] PLAN INTEGRATION */}
        <div className="msr-sec">
          <div className="msr-sec-head"><div><div className="msr-sec-eb">Plan integration</div><h2 className="msr-sec-h">How it changes today's plan</h2></div>
            <span className="msr-sec-note">Structural Bias × Sensor → one combined action.</span></div>
          <MsrPlanStrip data={data} />
        </div>

        {/* [C] CATALYSTS */}
        <MsrCatalysts data={data} />

        {/* [D] SENSOR DETAIL */}
        <MsrSensorDetail data={data} />

        {/* [E] WATCHLIST */}
        <MsrWatchlist data={data} />

        {/* [F] METHOD */}
        <MsrMethod data={data} />

        <div className="msr-foot">
          <img src="assets/logo/tank-mark.svg" alt="Tank’s Trading Desk" />
          <span className="msr-foot-c">Market Sensor is a volatility-regime context tool, not a trade trigger or directional call. Education only — not financial advice. Execution follows the published QQQ plan and risk rules. Operated from Singapore. Past performance is not indicative of future results.</span>
        </div>
      </div>
    </div>
  );
}

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