// Creation wizard: 6 steps. Atmosphere → Surface → Moons → Rings → Star → Name.
// Each step renders a control surface; a pinned live 3D preview stays visible.

const { useState, useEffect, useRef, useMemo } = React;

const WIZ_STEPS = [
  { id: 'atmosphere', label: 'Atmosphere' },
  { id: 'surface',    label: 'Surface'   },
  { id: 'moons',      label: 'Moons'     },
  { id: 'rings',      label: 'Rings'     },
  { id: 'star',       label: 'Star'      },
  { id: 'seal',       label: 'Seal'      },
];

function defaultSpec() {
  return {
    atmosphere: [{sym:'N',pct:60},{sym:'O',pct:30},{sym:'H₂O',pct:10}],
    surface: 'oceanic',
    moons: [{name:'Moon I', size:0.2, tint:'#ccd8ff'}],
    rings: { enabled: false, count: 1, tilt: 18, density: 0.5 },
    rotationHours: 24,
    orbitAU: 1.0,
    star: 'G',
    weather: 'mild',
    life: 'microbial',
    axial: 15,
    name: '',
    discoverer: '',
  };
}

// ============ Step 1: Atmosphere ============
// Atmospheric chemistry constants used for inline science hints.
const GREENHOUSE_SET  = new Set(['CO₂','CH4','H₂O','NH₃','O₃']);
const SHIELD_SET      = new Set(['O₃']);
const LIGHT_GAS_SET   = new Set(['H','He']); // escape easily from small/hot worlds
const BIOSIG_PAIR     = ['O','CH4'];         // disequilibrium suggests an active biosphere

function atmosphereAnalytics(atmosphere) {
  const els = window.PLANETALIN_ELEMENTS;
  const byS = new Map(els.map(e => [e.sym, e]));
  const total = atmosphere.reduce((s,a) => s+a.pct, 0) || 0;
  if (!total) return null;
  // Mass-weighted mean molecular mass (u)
  let mmm = 0, greenhouse = 0, lightGas = 0;
  for (const a of atmosphere) {
    const el = byS.get(a.sym);
    if (!el) continue;
    const frac = a.pct / total;
    mmm += el.mass * frac;
    if (GREENHOUSE_SET.has(a.sym)) greenhouse += frac;
    if (LIGHT_GAS_SET.has(a.sym))  lightGas   += frac;
  }
  const hasO   = atmosphere.some(a => a.sym === BIOSIG_PAIR[0] && a.pct > 0);
  const hasCH4 = atmosphere.some(a => a.sym === BIOSIG_PAIR[1] && a.pct > 0);
  const hasO3  = atmosphere.some(a => a.sym === 'O₃' && a.pct > 0);
  return {
    mmm,
    greenhouse,         // 0..1 — fraction by volume of GHGs
    lightGas,           // 0..1 — fraction of easily-escaping light gases
    biosignature: hasO && hasCH4,
    uvShield: hasO3,
    rayleighBlue: mmm > 20 && atmosphere.some(a => a.sym === 'N' || a.sym === 'O'),
  };
}

function StepAtmosphere({ spec, setSpec }) {
  const els = window.PLANETALIN_ELEMENTS;
  const inAtmos = (sym) => spec.atmosphere.find(a => a.sym === sym);
  const totalPct = spec.atmosphere.reduce((s,a) => s+a.pct, 0);
  const sci = atmosphereAnalytics(spec.atmosphere);

  function addElement(sym) {
    if (inAtmos(sym) || spec.atmosphere.length >= 5) return;
    const newAtm = [...spec.atmosphere, { sym, pct: 10 }];
    setSpec({ ...spec, atmosphere: newAtm });
  }
  function removeElement(sym) {
    setSpec({ ...spec, atmosphere: spec.atmosphere.filter(a => a.sym !== sym) });
  }
  function updatePct(sym, pct) {
    setSpec({
      ...spec,
      atmosphere: spec.atmosphere.map(a => a.sym === sym ? {...a, pct: Math.round(pct)} : a)
    });
  }
  function normalize() {
    if (totalPct === 0) return;
    setSpec({ ...spec, atmosphere: window.PLANETALIN.normalizeAtmosphere(spec.atmosphere) });
  }

  return (
    <div className="step-body">
      <div className="step-head">
        <div className="step-eyebrow">01 · Composition</div>
        <h2 className="step-title">What air will your world breathe?</h2>
        <p className="step-caption">Select up to 5 elements. Their signature colors blend into the atmosphere and drive the planet's palette.</p>
      </div>

      <div className="periodic-grid">
        {els.map(el => {
          const sel = inAtmos(el.sym);
          return (
            <button
              key={el.sym}
              className={`pt-cell ${sel ? 'is-sel' : ''}`}
              onClick={() => sel ? removeElement(el.sym) : addElement(el.sym)}
              style={{'--el-col': el.color, '--el-glow': el.glow}}
              title={`${el.name} (${el.mass} u) · ${el.spectrum}`}
            >
              <div className="pt-sym">{el.sym}</div>
              <div className="pt-name">{el.name}</div>
              <div className="pt-trait">{el.trait}</div>
            </button>
          );
        })}
      </div>

      <div className="mix-panel">
        <div className="mix-head">
          <div className="mix-label">MIXTURE · {totalPct}%</div>
          <button className="mini-btn" onClick={normalize} disabled={totalPct===0}>Normalize to 100</button>
        </div>
        {spec.atmosphere.length === 0 && (
          <div className="mix-empty">No elements selected yet. Tap above.</div>
        )}
        <div className="mix-bar">
          {spec.atmosphere.map(a => {
            const el = els.find(e => e.sym === a.sym);
            return (
              <div key={a.sym} className="mix-seg" style={{flex: a.pct, background: el.color}}>
                <span>{a.sym}</span>
              </div>
            );
          })}
        </div>
        <div className="mix-rows">
          {spec.atmosphere.map(a => {
            const el = els.find(e => e.sym === a.sym);
            return (
              <div key={a.sym} className="mix-row">
                <span className="mix-chip" style={{background: el.color}}>{el.sym}</span>
                <span className="mix-nm">
                  {el.name}
                  <span className="mix-mass">{el.mass} u</span>
                  <span className="mix-spec">{el.spectrum}</span>
                </span>
                <input type="range" min="1" max="100" value={a.pct} onChange={e => updatePct(a.sym, +e.target.value)} />
                <span className="mix-pct">{a.pct}%</span>
                <button className="mini-x" onClick={() => removeElement(a.sym)}>×</button>
              </div>
            );
          })}
        </div>
      </div>

      {sci && (
        <div className="atm-science">
          <div className="atm-sci-head">ATMOSPHERIC ANALYSIS</div>
          <div className="atm-sci-grid">
            <div className="sci-stat">
              <div className="sci-lbl">Mean molecular mass</div>
              <div className="sci-val">{sci.mmm.toFixed(1)} u</div>
              <div className="sci-hint">{sci.mmm < 10 ? 'Very light — escapes small worlds' : sci.mmm < 20 ? 'Light — retained only with enough gravity' : sci.mmm < 35 ? 'Earth-like weight' : 'Heavy — sinks, dense lower atmosphere'}</div>
            </div>
            <div className="sci-stat">
              <div className="sci-lbl">Greenhouse index</div>
              <div className="sci-val">{Math.round(sci.greenhouse*100)}%</div>
              <div className="sci-hint">{sci.greenhouse < 0.1 ? 'Transparent to IR — runs cool' : sci.greenhouse < 0.35 ? 'Moderate warming' : sci.greenhouse < 0.7 ? 'Strong greenhouse — surface baked' : 'Runaway greenhouse (Venus-type)'}</div>
            </div>
            <div className="sci-stat">
              <div className="sci-lbl">Light-gas fraction</div>
              <div className="sci-val">{Math.round(sci.lightGas*100)}%</div>
              <div className="sci-hint">{sci.lightGas > 0.3 ? 'H/He dominated — needs giant-world gravity to hold' : sci.lightGas > 0 ? 'Trace light gases may slowly escape' : 'Stable against Jeans escape'}</div>
            </div>
          </div>
          <div className="atm-badges">
            {sci.rayleighBlue && <span className="atm-badge">☁︎ Rayleigh-blue sky</span>}
            {sci.uvShield && <span className="atm-badge is-good">☀︎ UV shield · ozone absorbs 200–300 nm</span>}
            {sci.greenhouse > 0.6 && <span className="atm-badge is-warn">♨ Runaway greenhouse risk</span>}
            {sci.biosignature && <span className="atm-badge is-good">✦ O₂ + CH₄ disequilibrium — biosignature pair</span>}
            {sci.lightGas > 0.5 && <span className="atm-badge is-warn">↑ Light gases escape — needs Jovian gravity</span>}
          </div>
        </div>
      )}
    </div>
  );
}

// ============ Step 2: Surface ============
function StepSurface({ spec, setSpec }) {
  const surfaces = window.PLANETALIN_SURFACES;
  return (
    <div className="step-body">
      <div className="step-head">
        <div className="step-eyebrow">02 · Crust</div>
        <h2 className="step-title">What lies beneath the sky?</h2>
        <p className="step-caption">Choose the character of your world's surface, and the weather that moves across it.</p>
      </div>
      <div className="surface-grid">
        {surfaces.map(s => (
          <button
            key={s.id}
            className={`surface-card ${spec.surface===s.id ? 'is-sel' : ''}`}
            onClick={() => setSpec({...spec, surface: s.id})}
            style={{'--tint': s.tint}}
          >
            <div className="surface-orb"></div>
            <div className="surface-meta">
              <div className="surface-nm">{s.name}</div>
              <div className="surface-dt">{s.detail}</div>
            </div>
          </button>
        ))}
      </div>

      <div className="two-col">
        <div className="col-panel">
          <div className="col-label">Weather</div>
          <div className="pill-row">
            {['clear','mild','storms','auroras','inferno'].map(w => (
              <button key={w} className={`pill ${spec.weather===w?'is-sel':''}`} onClick={()=>setSpec({...spec, weather:w})}>{w}</button>
            ))}
          </div>
        </div>
        <div className="col-panel">
          <div className="col-label">Life indicators</div>
          <div className="pill-row">
            {['none','microbial','complex','intelligent'].map(w => (
              <button key={w} className={`pill ${spec.life===w?'is-sel':''}`} onClick={()=>setSpec({...spec, life:w})}>{w}</button>
            ))}
          </div>
        </div>
      </div>

      <div className="two-col">
        <div className="col-panel">
          <div className="col-label">Rotation · day length <span className="col-val">{spec.rotationHours} h</span></div>
          <input type="range" min="2" max="96" value={spec.rotationHours} onChange={e => setSpec({...spec, rotationHours:+e.target.value})} />
        </div>
        <div className="col-panel">
          <div className="col-label">Axial tilt <span className="col-val">{spec.axial}°</span></div>
          {/* Extended to 180° so retrograde worlds (Venus 177°, Uranus 98°) are expressible. */}
          <input type="range" min="0" max="180" step="0.1" value={spec.axial} onChange={e => setSpec({...spec, axial:+e.target.value})} />
        </div>
      </div>
    </div>
  );
}

// ============ Step 3: Moons ============
function StepMoons({ spec, setSpec }) {
  function addMoon() {
    if (spec.moons.length >= 5) return;
    const n = spec.moons.length;
    const names = ['I','II','III','IV','V'];
    setSpec({...spec, moons:[...spec.moons, { name:`Moon ${names[n]}`, size:0.15+Math.random()*0.15, tint:'#cccfe8' }]});
  }
  function removeMoon(i) {
    setSpec({...spec, moons: spec.moons.filter((_,idx)=>idx!==i)});
  }
  function updateMoon(i, patch) {
    setSpec({...spec, moons: spec.moons.map((m,idx)=> idx===i ? {...m,...patch} : m)});
  }

  return (
    <div className="step-body">
      <div className="step-head">
        <div className="step-eyebrow">03 · Satellites</div>
        <h2 className="step-title">How many moons circle your world?</h2>
        <p className="step-caption">Up to five. Each can be tinted and sized independently.</p>
      </div>

      <div className="moon-list">
        {spec.moons.map((m,i) => (
          <div className="moon-row" key={i}>
            <div className="moon-preview" style={{'--sz': 20 + m.size*50 + 'px', background: m.tint}} />
            <input className="moon-name" value={m.name} onChange={e => updateMoon(i, {name: e.target.value})} />
            <div className="moon-ctrl">
              <span className="tiny">size</span>
              <input type="range" min="0.05" max="0.4" step="0.01" value={m.size} onChange={e => updateMoon(i, {size: +e.target.value})} />
            </div>
            <input type="color" value={m.tint} onChange={e => updateMoon(i, {tint: e.target.value})} className="moon-color" />
            <button className="mini-x" onClick={() => removeMoon(i)}>×</button>
          </div>
        ))}
        {spec.moons.length === 0 && (
          <div className="empty-note">A lonely world. No moons.</div>
        )}
      </div>

      <button className="add-btn" onClick={addMoon} disabled={spec.moons.length>=5}>
        <span>+</span> add moon
      </button>
    </div>
  );
}

// ============ Step 4: Rings ============
function StepRings({ spec, setSpec }) {
  const r = spec.rings;
  return (
    <div className="step-body">
      <div className="step-head">
        <div className="step-eyebrow">04 · Rings</div>
        <h2 className="step-title">Will it wear a halo?</h2>
        <p className="step-caption">Dust and ice can orbit in bands around your planet. Not every world needs them.</p>
      </div>

      <div className="ring-toggle">
        <button className={`toggle-card ${!r.enabled?'is-sel':''}`} onClick={()=>setSpec({...spec, rings:{...r, enabled:false}})}>
          <div className="toggle-vis">
            <div className="vis-planet vis-bare" />
          </div>
          <div className="toggle-lbl">No rings</div>
        </button>
        <button className={`toggle-card ${r.enabled?'is-sel':''}`} onClick={()=>setSpec({...spec, rings:{...r, enabled:true}})}>
          <div className="toggle-vis">
            <div className="vis-planet vis-ringed">
              <div className="vis-ring" />
            </div>
          </div>
          <div className="toggle-lbl">With rings</div>
        </button>
      </div>

      {r.enabled && (
        <div className="ring-ctrls">
          <div className="col-panel">
            <div className="col-label">Bands <span className="col-val">{r.count}</span></div>
            <input type="range" min="1" max="5" value={r.count} onChange={e => setSpec({...spec, rings:{...r, count:+e.target.value}})} />
          </div>
          <div className="col-panel">
            <div className="col-label">Tilt <span className="col-val">{r.tilt}°</span></div>
            <input type="range" min="0" max="60" value={r.tilt} onChange={e => setSpec({...spec, rings:{...r, tilt:+e.target.value}})} />
          </div>
          <div className="col-panel">
            <div className="col-label">Density <span className="col-val">{Math.round(r.density*100)}%</span></div>
            <input type="range" min="0.1" max="1" step="0.05" value={r.density} onChange={e => setSpec({...spec, rings:{...r, density:+e.target.value}})} />
          </div>
        </div>
      )}
    </div>
  );
}

// ============ Step 5: Star ============
function StepStar({ spec, setSpec }) {
  const stars = window.PLANETALIN_STARS;
  // Range goes to 40 AU so Neptune (30 AU) and outer bodies are expressible.
  const ORBIT_MIN = 0.2, ORBIT_MAX = 40;

  const hz = window.PLANETALIN.habitableZone(spec.star);
  const regime = window.PLANETALIN.orbitRegime(spec.star, spec.orbitAU);
  const tempK = window.PLANETALIN.equilibriumTempK(spec.star, spec.orbitAU);
  const tempC = Math.round(tempK - 273.15);

  // HZ band position on the orbit slider, in % of the slider range.
  // Uses a log scale so tight inner orbits don't get crushed against the start.
  const lo = Math.log(ORBIT_MIN), hi = Math.log(ORBIT_MAX);
  const pctOf = au => Math.max(0, Math.min(100, ((Math.log(Math.max(ORBIT_MIN, au)) - lo) / (hi - lo)) * 100));
  const hzLeft = pctOf(hz.inner);
  const hzRight = pctOf(hz.outer);

  return (
    <div className="step-body">
      <div className="step-head">
        <div className="step-eyebrow">05 · Primary</div>
        <h2 className="step-title">Which sun does it orbit?</h2>
        <p className="step-caption">Stellar class shapes the colour of daylight. Orbital distance sets the season — and the habitable zone.</p>
      </div>

      <div className="star-grid">
        {stars.map(s => (
          <button
            key={s.id}
            className={`star-card ${spec.star===s.id?'is-sel':''}`}
            onClick={()=>setSpec({...spec, star:s.id})}
            style={{'--star-col': s.color}}
          >
            <div className="star-orb" />
            <div className="star-class">{s.name}</div>
            <div className="star-temp">{s.temp}</div>
            <div className="star-desc">{s.desc}</div>
          </button>
        ))}
      </div>

      <div className="col-panel">
        <div className="col-label">
          Orbital distance <span className="col-val">{spec.orbitAU.toFixed(2)} AU</span>
          <span className="col-sub">· {regime.label} · ~{tempC > -100 ? tempC : Math.round(tempK)+'K'}{tempC > -100 ? '°C' : ''}</span>
        </div>
        <div className="hz-meter" title="Conservative habitable zone (Kopparapu): √L-scaled">
          <div className="hz-band" style={{left: hzLeft+'%', width: Math.max(0, hzRight-hzLeft)+'%'}} />
        </div>
        <input type="range" min={ORBIT_MIN} max={ORBIT_MAX} step="0.01" value={spec.orbitAU} onChange={e => setSpec({...spec, orbitAU:+e.target.value})} />
        <div className="orbit-scale">
          <span>scorched</span><span>habitable {hz.inner.toFixed(2)}–{hz.outer.toFixed(2)} AU</span><span>frozen</span>
        </div>
        <div className="hz-note">{regime.detail}. Luminosity ≈ {hz.luminosity >= 1 ? hz.luminosity.toFixed(1) : hz.luminosity.toFixed(2)} L☉.</div>
      </div>
    </div>
  );
}

// ============ Step 6: Seal ============
function StepSeal({ spec, setSpec, onSeal, sealState }) {
  const [localName, setLocalName] = useState(spec.name);
  const [localDisc, setLocalDisc] = useState(spec.discoverer);
  const [cooldownMs, setCooldownMs] = useState(window.PLANETALIN.msUntilNextWindow());
  useEffect(() => { setSpec({...spec, name: localName, discoverer: localDisc}); }, [localName, localDisc]);
  useEffect(() => {
    const iv = setInterval(() => setCooldownMs(window.PLANETALIN.msUntilNextWindow()), 1000);
    return () => clearInterval(iv);
  }, []);

  const canCreate = cooldownMs === 0;
  const hrs = Math.floor(cooldownMs/3600000);
  const mins = Math.floor((cooldownMs%3600000)/60000);
  const secs = Math.floor((cooldownMs%60000)/1000);
  const cdLabel = hrs > 0 ? `${hrs}h ${String(mins).padStart(2,'0')}m` : `${mins}m ${String(secs).padStart(2,'0')}s`;

  return (
    <div className="step-body">
      <div className="step-head">
        <div className="step-eyebrow">06 · Seal</div>
        <h2 className="step-title">Name it. Sign it. Seal it.</h2>
        <p className="step-caption">Once sealed, the specification is permanent. You may fork it into a new world, but you may not alter this one.</p>
      </div>

      <div className="seal-form">
        <label className="seal-field">
          <span className="seal-lbl">Planet name</span>
          <input value={localName} onChange={e=>setLocalName(e.target.value)} placeholder="eg. Aethelion" maxLength="24" />
        </label>
        <label className="seal-field">
          <span className="seal-lbl">Discovered by</span>
          <input value={localDisc} onChange={e=>setLocalDisc(e.target.value)} placeholder="your name" maxLength="32" />
        </label>
      </div>

      <div className="seal-summary">
        <div className="summary-head">Specification</div>
        <dl>
          <dt>Atmosphere</dt><dd>{spec.atmosphere.map(a=>`${a.sym} ${a.pct}%`).join(' · ')||'—'}</dd>
          <dt>Surface</dt><dd>{spec.surface}</dd>
          <dt>Weather</dt><dd>{spec.weather} · life: {spec.life}</dd>
          <dt>Moons</dt><dd>{spec.moons.length ? spec.moons.map(m=>m.name).join(', ') : 'none'}</dd>
          <dt>Rings</dt><dd>{spec.rings.enabled ? `${spec.rings.count} bands @ ${spec.rings.tilt}°` : 'none'}</dd>
          <dt>Star</dt><dd>{spec.star}-type · {spec.orbitAU.toFixed(2)} AU</dd>
          <dt>Day</dt><dd>{spec.rotationHours}h · tilt {spec.axial}°</dd>
        </dl>
      </div>

      {!canCreate && sealState === 'idle' && (
        <div className="seal-cooldown-warn">
          <div className="cd-warn-lbl">SKY CLOSED</div>
          <div className="cd-warn-body">
            You've already shaped a world in the current window. Your spec is held here — you can come back and seal it in <strong>{cdLabel}</strong>.
          </div>
        </div>
      )}

      <button
        className={`seal-btn ${!canCreate && sealState==='idle' ? 'is-disabled-soft' : ''}`}
        disabled={!localName || !localDisc || sealState === 'sealing' || sealState === 'done'}
        onClick={onSeal}
      >
        {sealState === 'idle' && canCreate && <>Seal this world →</>}
        {sealState === 'idle' && !canCreate && <>Sky closed · {cdLabel}</>}
        {sealState === 'sealing' && <>Sealing…</>}
        {sealState === 'done' && <>Sealed ✓</>}
        {sealState === 'blocked' && <>Sky closed · {cdLabel}</>}
      </button>
    </div>
  );
}

// Global
window.PLANETALINWizard = { defaultSpec, StepAtmosphere, StepSurface, StepMoons, StepRings, StepStar, StepSeal, WIZ_STEPS };
