import { renderHook, act } from '@testing-library/react-native';
import { Audio } from 'expo-av';
import { useAudio } from '../useAudio';

// Mock expo-av modules
jest.mock('expo-av', () => ({
  Audio: {
    Sound: {
      createAsync: jest.fn().mockResolvedValue({ sound: { playAsync: jest.fn(), unloadAsync: jest.fn() } }),
    },
    setAudioModeAsync: jest.fn().mockResolvedValue({}),
  },
}));

describe('useAudio hook', () => {
  // Reset mocks after each test
  afterEach(() => {
    jest.clearAllMocks();
  });

  it('should configure audio when soundEnabled is true', async () => {
    renderHook(() => useAudio('test-sound.mp3', true));

    // Check that setAudioModeAsync was called with the right parameters
    expect(Audio.setAudioModeAsync).toHaveBeenCalledWith({
      allowsRecordingIOS: false,
      staysActiveInBackground: true,
      playsInSilentModeIOS: true,
      shouldDuckAndroid: true,
      playThroughEarpieceAndroid: false,
    });
  });

  it('should not configure audio when soundEnabled is false', async () => {
    renderHook(() => useAudio('test-sound.mp3', false));

    // Check that setAudioModeAsync was not called
    expect(Audio.setAudioModeAsync).not.toHaveBeenCalled();
  });

  it('should play sound when playSound is called and soundEnabled is true', async () => {
    const { result } = renderHook(() => useAudio('test-sound.mp3', true));

    await act(async () => {
      await result.current.playSound();
    });

    // Check that createAsync was called with the correct sound file
    expect(Audio.Sound.createAsync).toHaveBeenCalledWith('test-sound.mp3');
  });

  it('should not play sound when playSound is called and soundEnabled is false', async () => {
    const { result } = renderHook(() => useAudio('test-sound.mp3', false));

    await act(async () => {
      await result.current.playSound();
    });

    // Check that createAsync was not called
    expect(Audio.Sound.createAsync).not.toHaveBeenCalled();
  });

  it('should unload sound when component is unmounted', async () => {
    const mockUnloadAsync = jest.fn();
    (Audio.Sound.createAsync as jest.Mock).mockResolvedValueOnce({
      sound: {
        playAsync: jest.fn(),
        unloadAsync: mockUnloadAsync
      }
    });

    const { result, unmount } = renderHook(() => useAudio('test-sound.mp3', true));

    await act(async () => {
      await result.current.playSound();
    });

    unmount();

    // Check that unloadAsync was called
    expect(mockUnloadAsync).toHaveBeenCalled();
  });
});
