import { describe, expect, it } from 'vitest';
import { TUTORIAL_FADE_MS, TUTORIAL_MS, tutorialAlpha } from '../src/scenes/door/tutorialFade';

// Regression guard for the door-tutorial fade. The original implementation was
// `if (alpha > 0) tweens.add({ alpha: 0, duration: 800 })` inside update():
// each frame's new tween re-captured the still-positive alpha, so the guard
// never closed and DoorScene accumulated one live 800ms tween per frame
// (~1,100 by the end of a night). The fade is now this pure function; these
// tests pin the property that killed the tween version — it must actually
// reach 0 and stay there.

describe('tutorialAlpha', () => {
  it('holds at full alpha through the tutorial window', () => {
    expect(tutorialAlpha(0)).toBe(1);
    expect(tutorialAlpha(TUTORIAL_MS)).toBe(1);
  });

  it('fades linearly once the hold expires', () => {
    expect(tutorialAlpha(TUTORIAL_MS + TUTORIAL_FADE_MS / 2)).toBeCloseTo(0.5);
    expect(tutorialAlpha(TUTORIAL_MS + TUTORIAL_FADE_MS / 4)).toBeCloseTo(0.75);
  });

  it('reaches exactly 0 at fade end and never goes negative after', () => {
    expect(tutorialAlpha(TUTORIAL_MS + TUTORIAL_FADE_MS)).toBe(0);
    expect(tutorialAlpha(TUTORIAL_MS + TUTORIAL_FADE_MS + 1)).toBe(0);
    // A whole night later it is still pinned at 0 — the condition the old
    // tween-spawning guard could never satisfy.
    expect(tutorialAlpha(TUTORIAL_MS + 4 * 60 * 60 * 1000)).toBe(0);
  });

  it('is monotonically non-increasing frame over frame', () => {
    let prev = Infinity;
    for (let ms = 0; ms < TUTORIAL_MS + 2 * TUTORIAL_FADE_MS; ms += 16.67) {
      const a = tutorialAlpha(ms);
      expect(a).toBeLessThanOrEqual(prev);
      expect(a).toBeGreaterThanOrEqual(0);
      prev = a;
    }
  });
});
