import type { Stage } from './scenes/stage';
import { FLOOR_Y } from './scenes/stage';

/**
 * Dev harness — toastsim's single most valuable organ, transplanted.
 *
 * Drives the REAL sim deterministically at a fixed dt so "does it actually work"
 * is answered by measured numbers, not by squinting. Every helper returns a
 * stats object. Installed on window.__s in dev builds.
 *
 * Milestones add verbs here; nothing ships without a harness number behind it.
 */
export function installHarness(stage: Stage): void {
  const rest = (body: MatterJS.BodyType) =>
    Math.hypot(body.velocity.x, body.velocity.y) < 0.05 && Math.abs(body.angularVelocity) < 0.01;

  const step = (frames: number, dt = 1000 / 60): void => {
    stage.auto = false;
    for (let i = 0; i < frames; i++) stage.stepSim(dt);
  };

  /** Step until the box stops moving (or maxFrames). Returns frames elapsed. */
  const settle = (body: MatterJS.BodyType, maxFrames = 600): number => {
    stage.auto = false;
    let f = 0;
    for (; f < maxFrames; f++) {
      stage.stepSim();
      if (rest(body)) break;
    }
    return f;
  };

  const s = {
    stage,
    step,
    settle,

    /** M0 exit-bar: drop the box from height, let it settle, report where it landed. */
    drop(x = 640, y = 80) {
      stage.auto = false;
      const body = stage.matter.body;
      body.setPosition(stage.box, { x, y }, false);
      body.setVelocity(stage.box, { x: 0, y: 0 });
      body.setAngle(stage.box, 0, false);
      body.setAngularVelocity(stage.box, 0);
      const frames = settle(stage.box);
      const restY = +stage.box.position.y.toFixed(2);
      return {
        frames,
        restY,
        floorTopY: FLOOR_Y,
        gap: +(FLOOR_Y - 32 - restY).toFixed(2), // 0 ≈ sitting flush (half the 64px box)
        landed: rest(stage.box) && restY < FLOOR_Y + 8,
      };
    },
  };

  (window as { __s?: typeof s }).__s = s;
  // eslint-disable-next-line no-console
  console.log('[dev] __s ready — try __s.drop()');
}
