import { describe, it, expect } from 'vitest';

import {
  clampTime,
  formatTimecode,
  isTimeBased,
  expandedOrder,
  QUAD_LABELS,
} from './playbackModel';

describe('clampTime', () => {
  it('clamps within [0, duration]', () => {
    expect(clampTime(5, 10)).toBe(5);
    expect(clampTime(0, 10)).toBe(0);
    expect(clampTime(10, 10)).toBe(10);
  });

  it('clamps an over-duration time down to duration', () => {
    expect(clampTime(15, 10)).toBe(10);
  });

  it('clamps a negative time up to 0', () => {
    expect(clampTime(-3, 10)).toBe(0);
  });

  it('returns 0 for NaN / non-finite time', () => {
    expect(clampTime(NaN, 10)).toBe(0);
    expect(clampTime(Infinity, 10)).toBe(0);
  });

  it('returns 0 when duration is 0, NaN, or non-finite', () => {
    expect(clampTime(5, 0)).toBe(0);
    expect(clampTime(5, NaN)).toBe(0);
    expect(clampTime(5, -1)).toBe(0);
  });
});

describe('formatTimecode', () => {
  it('formats 0 as "0:00"', () => {
    expect(formatTimecode(0)).toBe('0:00');
  });

  it('zero-pads seconds under ten', () => {
    expect(formatTimecode(5)).toBe('0:05');
  });

  it('formats minutes and seconds (75 → "1:15")', () => {
    expect(formatTimecode(75)).toBe('1:15');
  });

  it('floors fractional seconds', () => {
    expect(formatTimecode(75.9)).toBe('1:15');
  });

  it('guards NaN / negative → "0:00"', () => {
    expect(formatTimecode(NaN)).toBe('0:00');
    expect(formatTimecode(-5)).toBe('0:00');
  });
});

describe('isTimeBased', () => {
  it('is true for the video / depth / segmentation quads (0,1,2)', () => {
    expect(isTimeBased(0)).toBe(true);
    expect(isTimeBased(1)).toBe(true);
    expect(isTimeBased(2)).toBe(true);
  });

  it('is false for the 3D recon quad (3)', () => {
    expect(isTimeBased(3)).toBe(false);
  });
});

describe('expandedOrder', () => {
  it('returns the natural 2×2 order when nothing is expanded', () => {
    expect(expandedOrder(null)).toEqual([0, 1, 2, 3]);
  });

  it('puts the expanded quad first, then the rest ascending', () => {
    expect(expandedOrder(2)).toEqual([2, 0, 1, 3]);
  });

  it('handles each expanded index', () => {
    expect(expandedOrder(0)).toEqual([0, 1, 2, 3]);
    expect(expandedOrder(3)).toEqual([3, 0, 1, 2]);
  });
});

describe('QUAD_LABELS', () => {
  it('carries the Vietnamese pane labels with diacritics', () => {
    expect(QUAD_LABELS[0]).toBe('Video gốc');
    expect(QUAD_LABELS[1]).toBe('Bản đồ độ sâu');
    expect(QUAD_LABELS[2]).toBe('Mặt nạ phân vùng');
    expect(QUAD_LABELS[3]).toBe('Tái tạo 3D');
  });
});
