import assert from "node:assert/strict";
import { describe, it } from "node:test";
import {
  AircraftController,
  createAircraftPoseSnapshot,
} from "../aircraft/index.ts";
import {
  PoseInterpolationBuffer,
  isEntityPoseSnapshot,
} from "../realtime/index.ts";

describe("playable aircraft realtime bridge", () => {
  it("publishes a strict geographic snapshot with deterministic flight axes", () => {
    const controller = new AircraftController({
      initialHeadingDeg: 90,
      initialSpeedMps: 60,
      initialAltitudeM: 1_500,
    });
    const state = controller.snapshot();
    const snapshot = createAircraftPoseSnapshot(
      { aircraftId: "aircraft-page-1", pilotActorId: "actor-page-1" },
      state,
      7,
      10_000,
    );
    assert.equal(isEntityPoseSnapshot(snapshot), true);
    assert.equal(snapshot.entity, "aircraft");
    assert.equal(snapshot.pose.space, "geographic");
    assert.ok(Math.abs(snapshot.velocity.xMps - state.speedMps) < 1e-10);
    assert.ok(Math.abs(snapshot.velocity.zMps) < 1e-10);
    assert.equal(snapshot.velocity.yMps, state.verticalSpeedMps);
  });

  it("feeds aircraft samples through the shared deterministic interpolation buffer", () => {
    const controller = new AircraftController({ initialHeadingDeg: 0, initialSpeedMps: 50 });
    const first = createAircraftPoseSnapshot(
      { aircraftId: "aircraft-page-1", pilotActorId: "actor-page-1" },
      controller.snapshot(),
      1,
      1_000,
    );
    controller.tick(1, { throttle: 1 });
    const second = createAircraftPoseSnapshot(
      { aircraftId: "aircraft-page-1", pilotActorId: "actor-page-1" },
      controller.snapshot(),
      2,
      2_000,
    );
    const buffer = new PoseInterpolationBuffer({ interpolationDelayMs: 0 });
    assert.equal(buffer.push(first), true);
    assert.equal(buffer.push(second), true);
    const sample = buffer.sample(1_500);
    assert.equal(sample?.mode, "interpolated");
    assert.equal(sample?.pose.space, "geographic");
    if (sample?.pose.space === "geographic" && first.pose.space === "geographic" && second.pose.space === "geographic") {
      assert.ok(sample.pose.lat >= Math.min(first.pose.lat, second.pose.lat));
      assert.ok(sample.pose.lat <= Math.max(first.pose.lat, second.pose.lat));
    }
  });

  it("rejects non-wire-safe identity and aircraft controls", () => {
    const controller = new AircraftController();
    assert.throws(() => createAircraftPoseSnapshot(
      { aircraftId: "", pilotActorId: "actor-page-1" },
      controller.snapshot(),
      1,
      1_000,
    ), RangeError);
    const valid = createAircraftPoseSnapshot(
      { aircraftId: "aircraft-page-1", pilotActorId: "actor-page-1" },
      controller.snapshot(),
      1,
      1_000,
    );
    assert.equal(isEntityPoseSnapshot({ ...valid, throttle: 1.01 }), false);
    assert.equal(isEntityPoseSnapshot({ ...valid, rollDeg: Number.NaN }), false);
  });
});
