import { isStuckToBottom, resolveAutoScrollBehavior } from './auto-scroll.rules';

describe('resolveAutoScrollBehavior', () => {
  const base = {
    newMessages: true,
    forceLocalSend: false,
    distanceFromBottom: 0,
    withinInitialGrace: false
  };

  it('does nothing when no new messages arrived', () => {
    expect(resolveAutoScrollBehavior({ ...base, newMessages: false })).toBe('none');
  });

  it('jumps instantly for the local user own send regardless of grace', () => {
    expect(resolveAutoScrollBehavior({ ...base, forceLocalSend: true })).toBe('instant');
    expect(resolveAutoScrollBehavior({ ...base, forceLocalSend: true, withinInitialGrace: true })).toBe('instant');
  });

  it('jumps instantly when near bottom while settling after a channel switch', () => {
    expect(resolveAutoScrollBehavior({ ...base, distanceFromBottom: 40, withinInitialGrace: true })).toBe('instant');
  });

  it('animates smoothly for live messages once settled and near bottom', () => {
    expect(resolveAutoScrollBehavior({ ...base, distanceFromBottom: 40, withinInitialGrace: false })).toBe('smooth');
  });

  it('shows the indicator (no scroll) when far from the bottom', () => {
    expect(resolveAutoScrollBehavior({ ...base, distanceFromBottom: 800 })).toBe('none');
    expect(resolveAutoScrollBehavior({ ...base, distanceFromBottom: 800, withinInitialGrace: true })).toBe('none');
  });

  it('honours a custom sticky threshold', () => {
    expect(resolveAutoScrollBehavior({ ...base, distanceFromBottom: 150, stickyThreshold: 100 })).toBe('none');

    expect(resolveAutoScrollBehavior({ ...base, distanceFromBottom: 80, stickyThreshold: 100 })).toBe('smooth');
  });
});

describe('isStuckToBottom', () => {
  it('is stuck when exactly at the bottom', () => {
    expect(isStuckToBottom(0)).toBe(true);
  });

  it('is stuck within the default sticky threshold', () => {
    expect(isStuckToBottom(300)).toBe(true);
    expect(isStuckToBottom(299)).toBe(true);
  });

  it('is not stuck once past the default threshold', () => {
    expect(isStuckToBottom(301)).toBe(false);
    expect(isStuckToBottom(2000)).toBe(false);
  });

  it('honours a custom threshold', () => {
    expect(isStuckToBottom(80, 100)).toBe(true);
    expect(isStuckToBottom(150, 100)).toBe(false);
  });

  it('treats negative overscroll distances as stuck', () => {
    expect(isStuckToBottom(-20)).toBe(true);
  });
});
