import { describe, it, expect } from 'vitest';
import { lockAxis, canScrollFurther, resist, shouldCommit, neighborIndex } from './tab-swipe';

describe('lockAxis', () => {
  it('stays null until past the threshold', () => {
    expect(lockAxis(3, 2)).toBe(null);
    expect(lockAxis(7, 7)).toBe(null);
  });
  it('locks to the dominant axis past threshold', () => {
    expect(lockAxis(20, 4)).toBe('h');
    expect(lockAxis(4, 20)).toBe('v');
    expect(lockAxis(12, 12)).toBe('h'); // tie → horizontal
  });
});

describe('canScrollFurther', () => {
  const el = { scrollLeft: 50, scrollWidth: 300, clientWidth: 100 }; // max=200
  it('true when there is room in the finger direction', () => {
    expect(canScrollFurther(el, +1)).toBe(true); // moving right, scrollLeft>0
    expect(canScrollFurther(el, -1)).toBe(true); // moving left, room on right
  });
  it('false at the respective edge', () => {
    expect(canScrollFurther({ ...el, scrollLeft: 0 }, +1)).toBe(false);
    expect(canScrollFurther({ ...el, scrollLeft: 200 }, -1)).toBe(false);
  });
  it('false when not scrollable', () => {
    expect(canScrollFurther({ scrollLeft: 0, scrollWidth: 100, clientWidth: 100 }, -1)).toBe(false);
  });
});

describe('resist', () => {
  it('is 1:1 when a neighbor exists', () => {
    expect(resist(80, true, 360)).toBe(80);
  });
  it('rubber-bands (smaller, same sign) with no neighbor', () => {
    const r = resist(120, false, 360);
    expect(Math.sign(r)).toBe(1);
    expect(Math.abs(r)).toBeLessThan(120);
  });
});

describe('shouldCommit', () => {
  it('commits past max(60, 22% width) with a neighbor', () => {
    expect(shouldCommit(-100, 360, true)).toBe(true); // 22%*360=79.2, 100>79
    expect(shouldCommit(-70, 360, true)).toBe(false); // 70<79
    expect(shouldCommit(-70, 200, true)).toBe(true);  // max(60,44)=60, 70>60
  });
  it('never commits without a neighbor', () => {
    expect(shouldCommit(-300, 360, false)).toBe(false);
  });
});

describe('neighborIndex', () => {
  it('drag left → next, drag right → prev', () => {
    expect(neighborIndex(1, -10, 4)).toBe(2);
    expect(neighborIndex(1, 10, 4)).toBe(0);
  });
  it('null at the edges', () => {
    expect(neighborIndex(3, -10, 4)).toBe(null);
    expect(neighborIndex(0, 10, 4)).toBe(null);
    expect(neighborIndex(1, 0, 4)).toBe(null);
  });
});
