/* PRAXIS Loop — Altitude 1 & 2: Universe + Sector constellation */
/* global React, Kicker, Chip, MasteryBar, Ring, Btn, StatCell, useCountUp */
const { useState: useStateU, useEffect: useEffectU, useRef: useRefU } = React;

/* ════════════════════════════════════════════════════════════════════════
   UNIVERSE — the orientation altitude. Full cosmic drama.
   ════════════════════════════════════════════════════════════════════════ */
function UniverseScreen({ lex, focus, onFocus, onDescend }) {
  const { SECTORS, SECTOR_META, ramp } = window.PRAXIS;
  const labelRefs = useRefU({});

  // imperative label positioning — tracks the canvas camera at 60fps
  const placeLabel = (el, s) => {
    if (!el || !window.PraxisCosmos) return;
    const p = window.PraxisCosmos.project(s.x, s.y);
    if (Number.isFinite(p.x) && (p.x || p.y)) {
      // sit just under the nebula's edge; -58 corrects for the stage's topbar offset
      const rp = window.PraxisCosmos.projectRadius(s.r);
      el.style.transform = `translate(-50%, 0) translate(${p.x}px, ${p.y + rp * 0.52 + 10 - 58}px)`;
    }
  };
  useEffectU(() => {
    const off = window.PraxisCosmos.onTick(() => {
      for (const s of SECTORS) placeLabel(labelRefs.current[s.id], s);
    });
    return off;
  }, []);

  const focused = focus ? SECTORS.find(s => s.id === focus) : null;
  const meta = focused ? SECTOR_META[focused.id] : null;
  const netStars = window.PRAXIS.STARS.networking;

  return (
    <div className="lp-screen lp-universe">
      {/* sector labels riding the cosmos */}
      <div className="lp-sector-labels" aria-hidden="false">
        {SECTORS.map(s => {
          const m = SECTOR_META[s.id];
          return (
            <button key={s.id}
              ref={el => { labelRefs.current[s.id] = el; placeLabel(el, s); }}
              className={`lp-seclabel ${focus === s.id ? 'is-focus' : ''} ${focus && focus !== s.id ? 'is-dim' : ''}`}
              onMouseEnter={() => window.PraxisSound.hover()}
              onClick={() => { window.PraxisSound.tick(); onFocus(s.id); }}>
              <span className="lp-seclabel__name">{s.name}</span>
              <span className="lp-seclabel__meta mono">{m.stars} stars · mastery <i style={{ color: ramp(m.avg), fontStyle: 'normal' }}>{m.avg}</i></span>
            </button>
          );
        })}
      </div>

      {/* left: readiness instrument */}
      <aside className="lp-uni-left dock dock-1" aria-label="Universe readiness">
        <Ring value={62} size={196} label={lex.readiness} sub="▲ +4 this cycle" />
        <div className="lp-uni-stats panel panel--glass dock dock-3">
          <StatCell k="coverage" v="77%" />
          <StatCell k="due today" v="1" tone="var(--decay)" />
          <StatCell k="sectors" v="13" />
        </div>
      </aside>

      {/* right: focused sector inspector */}
      {focused ? (
        <aside className="lp-inspector panel panel--glass dock-l" aria-label="Sector inspector" key={focused.id}>
          <Kicker tone={`hsl(${focused.hue} 70% 70%)`}>● focused {lex.sector.toLowerCase()}</Kicker>
          <h2 className="title lp-inspector__title">{focused.name}</h2>
          <p className="lp-inspector__lede">
            {meta.stars} concepts mapped · avg mastery <b className="data" style={{ color: ramp(meta.avg) }}>{meta.avg}</b>.
            {focused.id === 'networking' ? ' The request path, atomized. One star is decaying.' : ' Survey pending — enter to chart this region.'}
          </p>
          {focused.id === 'networking' ? (
            <div className="lp-inspector__rows">
              {netStars.map((st, i) => (
                <div className="lp-irow" key={st.id} style={{ animationDelay: `${i * 60}ms` }}>
                  <div>
                    <div className="lp-irow__name">{st.name}</div>
                    <div className="lp-irow__slug mono">{st.slug}</div>
                  </div>
                  <div className="lp-irow__m">
                    <span className="data" style={{ color: ramp(st.mastery) }}>{st.mastery}</span>
                    <MasteryBar value={st.mastery} />
                  </div>
                </div>
              ))}
            </div>
          ) : null}
          {focused.id === 'networking' ? (
            <div style={{ marginTop: 'var(--s5)' }}>
              <Kicker>today's trajectory</Kicker>
              <div className="lp-traj">
                {[['Warm recall · done', 'is-done'], ['Source repair · now', 'is-next'], ['Application drill', ''], ['Pressure gauntlet', ''], ['Evidence capture', '']].map(([t, cls], i) => (
                  <div key={t} className={`lp-traj__row ${cls}`} style={{ animationDelay: `${300 + i * 60}ms` }}>
                    <span className="lp-traj__dot" aria-hidden="true"></span>
                    <span className="lp-traj__name">{t}</span>
                  </div>
                ))}
              </div>
            </div>
          ) : null}
          <Btn primary style={{ width: '100%', marginTop: 'var(--s5)' }}
               onClick={() => onDescend(focused.id)}>
            {lex.cta}
          </Btn>
        </aside>
      ) : (
        <aside className="lp-inspector lp-inspector--empty panel panel--glass dock-l" aria-label="Orientation inspector">
          <Kicker>orientation</Kicker>
          <h2 className="title lp-inspector__title">{lex.universe}</h2>
          <p className="lp-inspector__lede">{lex.tagline}</p>
          <p className="lp-inspector__hint mono">click a {lex.sector.toLowerCase()} to concentrate</p>
        </aside>
      )}
    </div>
  );
}

/* ════════════════════════════════════════════════════════════════════════
   SECTOR — the constellation altitude. Stars, prerequisite paths, decay.
   ════════════════════════════════════════════════════════════════════════ */
function SectorScreen({ lex, sectorId, selected, onSelect, onOpenStar }) {
  const { SECTORS, STARS, STAR_EDGES, ramp } = window.PRAXIS;
  const sector = SECTORS.find(s => s.id === sectorId) || SECTORS[0];
  const stars = STARS.networking;
  const edges = STAR_EDGES.networking;
  const sel = stars.find(s => s.id === selected) || stars.find(s => s.id === 'net-bgp');

  const pos = id => stars.find(s => s.id === id);

  return (
    <div className="lp-screen lp-sector">
      <header className="lp-sector__head dock dock-1">
        <Kicker tone={`hsl(${sector.hue} 70% 70%)`}>{lex.sector} · {stars.length} stars · 1 decaying</Kicker>
        <h1 className="display" style={{ fontSize: 'clamp(2.2rem, 4vw, 3.2rem)' }}>{sector.name}</h1>
      </header>

      {/* the constellation stage */}
      <div className="lp-const">
        <svg className="lp-const__edges" viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true">
          {edges.map(([a, b], i) => {
            const A = pos(a), B = pos(b);
            return (
              <line key={i}
                x1={A.x * 100} y1={A.y * 100} x2={B.x * 100} y2={B.y * 100}
                className={`lp-const__edge ${(sel && (a === sel.id || b === sel.id)) ? 'is-hot' : ''}`}
                style={{ animationDelay: `${250 + i * 140}ms` }}
                pathLength="1"></line>
            );
          })}
        </svg>
        {stars.map((st, i) => (
          <button key={st.id}
            className={`lp-star ${sel && sel.id === st.id ? 'is-sel' : ''} ${st.mastery < 40 ? 'is-decay' : ''}`}
            style={{ left: `${st.x * 100}%`, top: `${st.y * 100}%`, animationDelay: `${200 + i * 110}ms`,
                     '--star-c': ramp(st.mastery) }}
            onMouseEnter={() => window.PraxisSound.hover()}
            onClick={() => { window.PraxisSound.tick(); onSelect(st.id); }}>
            <span className="lp-star__core" aria-hidden="true"></span>
            <span className="lp-star__label">
              <span className="lp-star__name">{st.name}</span>
              <span className="lp-star__m mono">{st.mastery < 40 ? '⚠ ' : ''}{st.mastery} · due {st.due}</span>
            </span>
          </button>
        ))}
      </div>

      {/* star inspector */}
      {sel ? (
        <aside className="lp-inspector panel panel--glass dock-l" aria-label="Star inspector" key={sel.id}>
          <Kicker tone={sel.mastery < 40 ? 'var(--decay)' : 'var(--cyan)'}>
            {sel.mastery < 40 ? '● decaying star' : '● star'} · {sel.slug}
          </Kicker>
          <h2 className="title lp-inspector__title">{sel.name}</h2>
          <div className="lp-inspector__gauge">
            <div className="lp-inspector__gauge-num">
              <span className="data" style={{ fontSize: '2.1rem', color: ramp(sel.mastery) }}>{sel.mastery}</span>
              <span className="caption">mastery</span>
              <span className={`lp-trend mono ${sel.trend >= 0 ? 'is-up' : 'is-down'}`}>
                {sel.trend >= 0 ? '▲' : '▼'} {Math.abs(sel.trend)}
              </span>
            </div>
            <MasteryBar value={sel.mastery} height={6} />
          </div>
          <p className="lp-inspector__lede">{sel.gist}</p>
          <div className="lp-inspector__facts">
            <div className="lp-fact"><span className="kicker">due</span><b className="data" style={{ color: sel.due === 'TODAY' ? 'var(--decay)' : 'var(--text-primary)' }}>{sel.due}</b></div>
            <div className="lp-fact"><span className="kicker">evidence</span><b className="data">{sel.evidence} entries</b></div>
            <div className="lp-fact"><span className="kicker">last drill</span><b className="data">{sel.lastDrill}</b></div>
          </div>
          <Btn primary style={{ width: '100%', marginTop: 'var(--s5)' }} onClick={() => onOpenStar(sel.id)}>
            OPEN {lex.star.toUpperCase()} ↓
          </Btn>
        </aside>
      ) : null}
    </div>
  );
}

Object.assign(window, { UniverseScreen, SectorScreen });
