/* ============================================================
   Scene — paper-cutout parallax world + the rocket.
   window.Scene({ t, mult, phase, ejecting }) -> background + rocket
   Camera follows altitude; sky color + star opacity driven by mult.
   ============================================================ */
(function () {
  const { useMemo } = React;
  const E = window.Engine;
  /* deterministic RNG so star/cloud fields don't reshuffle each frame */
  function rng(seed) { return () => { seed = (seed * 1103515245 + 12345) & 0x7fffffff; return seed / 0x7fffffff; }; }

  /* sky gradient by "progress" p (0 ground .. 1 deep space) */
  function skyFor(p) {
    if (p < 0.18) { return `linear-gradient(180deg, #7cc6ec 0%, #aee3f5 60%, #cdeefb 100%)`; }
    if (p < 0.4)  { return `linear-gradient(180deg, #2f7fc4 0%, #5bb8e6 70%, #8fd2ef 100%)`; }
    if (p < 0.6)  { return `linear-gradient(180deg, #16356f 0%, #2a6db0 80%, #4a93cf 100%)`; }
    if (p < 0.78) { return `linear-gradient(180deg, #0a1336 0%, #15214a 75%, #243a73 100%)`; }
    return `linear-gradient(180deg, #04060f 0%, #070a1f 70%, #0d1230 100%)`;
  }

  function Stars({ seed, count, h }) {
    const stars = useMemo(() => {
      const r = rng(seed); const out = [];
      for (let i = 0; i < count; i++) {
        const big = r() > 0.86;
        out.push({ x: r() * 100, y: r() * h, s: big ? 3 : (r() > 0.5 ? 2 : 1.4), o: 0.5 + r() * 0.5 });
      }
      return out;
    }, [seed, count, h]);
    return stars.map((s, i) => <span key={i} className="star" style={{ left: s.x + '%', top: s.y + 'px', width: s.s, height: s.s, opacity: s.o }} />);
  }

  function Cloud({ x, y, scale, op }) {
    return (
      <div className="cloud" style={{ left: x + '%', top: y + 'px', transform: `scale(${scale})`, opacity: op }}>
        <b style={{ width: 64, height: 64, left: 0, top: 8 }} />
        <b style={{ width: 86, height: 86, left: 34, top: 0 }} />
        <b style={{ width: 64, height: 64, left: 92, top: 12 }} />
        <b style={{ width: 130, height: 44, left: 6, top: 44, borderRadius: 30 }} />
      </div>
    );
  }

  window.Scene = function Scene({ t, mult, phase, boostersOff }) {
    const E2 = E;
    // sky + stars follow the CAMERA (so a falling/descending camera reverses them)
    const visMult = E2.multAt(Math.max(0, t));
    const p = Math.min(1, visMult / 6);

    // camera altitude in px-space: compress real altitude so landmarks pace nicely
    const camKm = E2.altAt(Math.max(0, t));
    const camY = Math.log(camKm + 1) * 240;     // px the world has scrolled up

    // place a world landmark given the multiplier it lives at
    const place = (landmarkMult) => {
      const km = E2.altAt(E2.tForMult(landmarkMult));
      const worldY = Math.log(km + 1) * 240;
      return 560 + (camY - worldY);
    };

    const starOp = Math.max(0, Math.min(1, (visMult - 0.6) / 1.4));
    const cloudScroll = (camY * 1.4) % 1400;

    return (
      <React.Fragment>
        <div className="sky" style={{ background: skyFor(p) }} />

        {/* stars (fade in as we climb) */}
        <div className="starfield" style={{ opacity: starOp, transform: `translateY(${(camY * 0.25) % 300}px)` }}>
          <Stars seed={7} count={70} h={1100} />
        </div>

        {/* moon + planets as landmark sprites */}
        <div className="landmark" style={{ transform: `translate(-50%, ${place(3.0) - 80}px)`, left: '64%' }}>
          <div className="moon-body" />
        </div>
        <div className="landmark" style={{ transform: `translate(-50%, ${place(5.0) - 80}px)`, left: '30%' }}>
          <div className="planet mars" />
        </div>
        <div className="landmark" style={{ transform: `translate(-50%, ${place(10.0) - 80}px)`, left: '60%' }}>
          <div className="planet jup"><span className="ring" /></div>
        </div>

        {/* clouds drift band (visible low) */}
        <div className="bg-layer" style={{ opacity: Math.max(0, 1 - p * 2.4), transform: `translateY(${cloudScroll - 200}px)` }}>
          <Cloud x={8} y={120} scale={0.7} op={0.95} />
          <Cloud x={58} y={300} scale={1} op={0.9} />
          <Cloud x={20} y={560} scale={0.85} op={0.92} />
          <Cloud x={62} y={820} scale={0.6} op={0.85} />
          <Cloud x={30} y={1040} scale={0.95} op={0.9} />
        </div>

        {/* ground assembly (scrolls away fast) */}
        <div className="ground" style={{ transform: `translateY(${camY}px)`, opacity: camY > 520 ? 0 : 1, transition: 'opacity .4s' }}>
          <div className="hill back" />
          <div className="bldg" style={{ left: '12%', width: 38, height: 90, background: 'var(--paper-bldg-1)' }}>
            <i style={{ left: 8, top: 12 }} /><i style={{ right: 8, top: 12 }} /><i style={{ left: 8, top: 34 }} /><i style={{ right: 8, top: 34 }} />
          </div>
          <div className="bldg" style={{ left: '24%', width: 30, height: 64, background: 'var(--paper-bldg-2)' }}>
            <i style={{ left: 6, top: 10 }} /><i style={{ right: 6, top: 10 }} />
          </div>
          <div className="bldg" style={{ right: '16%', width: 44, height: 110, background: 'var(--paper-bldg-3)' }}>
            <i style={{ left: 9, top: 14 }} /><i style={{ right: 9, top: 14 }} /><i style={{ left: 9, top: 40 }} /><i style={{ right: 9, top: 40 }} />
          </div>
          <div className="tree" style={{ left: '6%' }}><span className="top" /><span className="trunk" /></div>
          <div className="tree" style={{ right: '7%' }}><span className="top" /><span className="trunk" /></div>
          <div className="tree" style={{ right: '30%', bottom: 100 }}><span className="top" style={{ width: 36, height: 36 }} /><span className="trunk" /></div>
          <div className="hill" />
        </div>
      </React.Fragment>
    );
  };

  /* ---- the rocket itself (separate so HUD can sit between bg and it) ---- */
  window.RocketSprite = function RocketSprite({ t, mult, phase, riseY, tilt, boostersOff, ejecting, flameOn, ignition = 0 }) {
    // ignition (0..1) during countdown builds the flame + smoke before flameOn
    const igniting = ignition > 0 && !flameOn;
    const flameScale = flameOn ? (0.7 + Math.min(1.6, mult) * 0.5) : (0.15 + ignition * 0.55);
    return (
      <div className="rocket-wrap" style={{ left: '50%', bottom: riseY, transform: `translateX(-50%) rotate(${tilt}deg)` }}>
        <div className="rocket" style={{ transform: igniting ? `translateX(${(Math.random() - 0.5) * ignition * 4}px)` : 'none' }}>
          {/* detachable boosters */}
          <div className="booster l" style={boosterStyle('l', boostersOff)} />
          <div className="booster r" style={boosterStyle('r', boostersOff)} />

          <div className="r-fin l" /><div className="r-fin r" />
          <div className="r-body" />
          <div className="r-nose" />
          <div className="r-window" />

          {/* astronaut head poking out the convertible side */}
          <div className="astro" style={{ transform: ejecting ? 'translate(46px,-150px) rotate(40deg)' : 'none', opacity: ejecting ? 0 : 1 }}>
            <div className="helmet"><span className="visor" /></div>
          </div>

          <div className={'flame' + (flameOn || igniting ? ' on' : '')} style={{ opacity: flameOn ? 1 : ignition, transform: `translateX(-50%) scaleY(${flameScale})` }}>
            <span className="f1" /><span className="f2" /><span className="f3" />
          </div>

          {/* launch smoke billowing at the pad during ignition + blastoff */}
          {(igniting || phase === 'blastoff') && <LaunchSmoke intensity={flameOn ? 1 : ignition} />}
        </div>
      </div>
    );
  };

  function LaunchSmoke({ intensity }) {
    const puffs = useMemo(() => Array.from({ length: 10 }, (_, i) => ({
      id: i, x: (Math.random() - 0.5) * 90, sz: 26 + Math.random() * 40,
      delay: Math.random() * 1.1, dur: 1.1 + Math.random() * 1.1, drift: (Math.random() - 0.5) * 70,
    })), []);
    return (
      <div className="launch-smoke" style={{ opacity: 0.35 + intensity * 0.65 }}>
        {puffs.map(p => (
          <span key={p.id} className="puff" style={{
            left: `calc(50% + ${p.x}px)`, width: p.sz, height: p.sz,
            ['--drift']: p.drift + 'px',
            animation: `puff ${p.dur}s ease-out ${p.delay}s infinite`,
          }} />
        ))}
      </div>
    );
  }

  /* ---- astronaut parachuting down after eject (sells the fall) ---- */
  window.Parachutist = function Parachutist() {
    return (
      <div className="chutist">
        <div className="chutist-sway">
          <div className="canopy" />
          <svg className="chute-strings" viewBox="0 0 80 46" width="80" height="46"><path d="M6 6 L40 44 M28 4 L40 44 M52 4 L40 44 M74 6 L40 44" stroke="#cdd9e4" strokeWidth="1.4" fill="none" /></svg>
          <div className="chutist-astro"><span className="helmet"><span className="visor" /></span><span className="chutist-body" /></div>
        </div>
      </div>
    );
  };

  function boosterStyle(side, off) {
    const base = {
      position: 'absolute', bottom: 26, width: 20, height: 70, borderRadius: 12,
      background: 'linear-gradient(90deg,#bcbfc6,#e7eaef)', boxShadow: 'var(--paper-sh)', zIndex: -1,
      transition: 'transform .9s cubic-bezier(.3,.6,.4,1), opacity .9s', transformOrigin: '50% 0%',
    };
    if (side === 'l') base.left = -16; else base.right = -16;
    if (off) {
      base.opacity = 0;
      base.transform = side === 'l' ? 'translate(-40px,120px) rotate(-50deg)' : 'translate(40px,120px) rotate(50deg)';
    }
    return base;
  }
})();
