import { describe, expect, it } from 'vitest';
import { STAGE_HEIGHT, STAGE_WIDTH, fitStage } from './stage';

describe('fitStage', () => {
  it('maps a 1080p TV 1:1 and a 4K TV at 2x with no letterbox', () => {
    expect(fitStage(1920, 1080)).toEqual({ scale: 1, offsetX: 0, offsetY: 0 });
    expect(fitStage(3840, 2160)).toEqual({ scale: 2, offsetX: 0, offsetY: 0 });
  });

  it('scales a 720p TV down to two thirds', () => {
    const fit = fitStage(1280, 720);
    expect(fit.scale).toBeCloseTo(2 / 3, 10);
    expect(fit.offsetX).toBe(0);
    expect(fit.offsetY).toBe(0);
  });

  it('pillarboxes a wider-than-16:9 viewport and centres the canvas', () => {
    const fit = fitStage(2560, 1080);
    expect(fit.scale).toBe(1);
    expect(fit.offsetX).toBe(320);
    expect(fit.offsetY).toBe(0);
  });

  it('letterboxes a taller viewport (phone in portrait, 4:3 TV)', () => {
    const fit = fitStage(390, 844);
    expect(fit.scale).toBeCloseTo(390 / STAGE_WIDTH, 10);
    expect(fit.offsetX).toBe(0);
    expect(fit.offsetY).toBe(Math.floor((844 - STAGE_HEIGHT * fit.scale) / 2));

    const fourThree = fitStage(1024, 768);
    expect(fourThree.scale).toBeCloseTo(1024 / 1920, 10);
    expect(fourThree.offsetY).toBe(96);
  });

  it('never overflows the viewport and keeps whole-pixel offsets', () => {
    for (const [w, h] of [
      [1366, 768],
      [1600, 900],
      [801, 451],
      [1919, 1081],
    ] as const) {
      const fit = fitStage(w, h);
      expect(STAGE_WIDTH * fit.scale).toBeLessThanOrEqual(w + 1e-9);
      expect(STAGE_HEIGHT * fit.scale).toBeLessThanOrEqual(h + 1e-9);
      expect(Number.isInteger(fit.offsetX)).toBe(true);
      expect(Number.isInteger(fit.offsetY)).toBe(true);
    }
  });

  it('returns a zero scale for an unmeasured or invalid viewport', () => {
    expect(fitStage(0, 0)).toEqual({ scale: 0, offsetX: 0, offsetY: 0 });
    expect(fitStage(Number.NaN, 720)).toEqual({ scale: 0, offsetX: 0, offsetY: 0 });
    expect(fitStage(-5, 720)).toEqual({ scale: 0, offsetX: 0, offsetY: 0 });
  });
});
