import { describe, expect, it } from 'vitest';
import { BREAK_AT, RACK_GLASSES, freshRack, stepRack, turnSharpness } from '../../src/scenes/floor/glassie';

describe('the glassie run (pure physics)', () => {
  it('a smooth walk settles the rack and breaks nothing', () => {
    let r = { glasses: RACK_GLASSES, wobble: 0.6 };
    let broke = 0;
    for (let i = 0; i < 120; i++) {
      const out = stepRack(r, 16, false, 0);
      r = out.rack;
      broke += out.broke;
    }
    expect(broke).toBe(0);
    expect(r.wobble).toBe(0);
    expect(r.glasses).toBe(RACK_GLASSES);
  });

  it('two quick crowd bumps break a glass; the wobble sheds with it', () => {
    let r = freshRack();
    r = stepRack(r, 16, true, 0).rack;
    expect(r.glasses).toBe(RACK_GLASSES); // one bump is a scare, not a smash
    const out = stepRack(r, 16, true, 0);
    expect(out.broke).toBe(1);
    expect(out.rack.glasses).toBe(RACK_GLASSES - 1);
    expect(out.rack.wobble).toBeLessThan(BREAK_AT);
  });

  it('sawing the stick hard eventually costs glass even with no crowd', () => {
    let r = freshRack();
    let broke = 0;
    for (let i = 0; i < 300; i++) {
      const out = stepRack(r, 16, false, 1);
      r = out.rack;
      broke += out.broke;
    }
    expect(broke).toBeGreaterThan(0);
  });

  it('a rack cannot go below zero glasses', () => {
    const r = { glasses: 1, wobble: 0.99 };
    const out = stepRack(r, 16, true, 1);
    expect(out.rack.glasses).toBe(0);
    const again = stepRack(out.rack, 16, true, 1);
    expect(again.rack.glasses).toBe(0);
    expect(again.broke).toBe(0);
  });

  it('turnSharpness is 0 for steady cruise, 1 for a full reversal', () => {
    expect(turnSharpness(100, 0, 100, 0, 116)).toBe(0);
    expect(turnSharpness(116, 0, -116, 0, 116)).toBe(1);
    expect(turnSharpness(0, 0, 60, 0, 0)).toBe(0); // junk maxSpeed is inert
  });
});
