import { renderHook, act } from '@testing-library/react';
import useAccessibilityMessage from '../useAccessibilityMessage';

describe('useAccessibilityMessage', () => {
  beforeEach(() => {
    jest.useFakeTimers();
    jest.clearAllMocks();
  });

  afterEach(() => {
    jest.useRealTimers();
  });

  it('initializes with an empty accessibility message', () => {
    const { result } = renderHook(() => useAccessibilityMessage());

    expect(result.current.accessibilityMessage).toBe('');
  });

  it('sets announcement message after the timeout delay', () => {
    const { result } = renderHook(() => useAccessibilityMessage());

    act(() => {
      result.current.announce('Post opened');
    });

    expect(result.current.accessibilityMessage).toBe('');

    act(() => {
      jest.advanceTimersByTime(50);
    });

    expect(result.current.accessibilityMessage).toBe('Post opened');
  });

  it('replaces any pending announcement with the latest one', () => {
    const { result } = renderHook(() => useAccessibilityMessage());

    act(() => {
      result.current.announce('First message');
      jest.advanceTimersByTime(25);
      result.current.announce('Second message');
    });

    act(() => {
      jest.advanceTimersByTime(49);
    });

    expect(result.current.accessibilityMessage).toBe('');

    act(() => {
      jest.advanceTimersByTime(1);
    });

    expect(result.current.accessibilityMessage).toBe('Second message');
  });

  it('clears and re-announces the same message', () => {
    const { result } = renderHook(() => useAccessibilityMessage());

    act(() => {
      result.current.announce('Same message');
      jest.advanceTimersByTime(50);
    });

    expect(result.current.accessibilityMessage).toBe('Same message');

    act(() => {
      result.current.announce('Same message');
    });

    expect(result.current.accessibilityMessage).toBe('');

    act(() => {
      jest.advanceTimersByTime(50);
    });

    expect(result.current.accessibilityMessage).toBe('Same message');
  });

  it('clears pending timeout on unmount', () => {
    const clearTimeoutSpy = jest.spyOn(window, 'clearTimeout');
    const { result, unmount } = renderHook(() => useAccessibilityMessage());

    act(() => {
      result.current.announce('Will not be announced');
    });

    unmount();

    expect(clearTimeoutSpy).toHaveBeenCalled();

    clearTimeoutSpy.mockRestore();
  });
});