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

describe('useAudioPlayer', () => {
  test('initializes with correct default state', () => {
    const { result } = renderHook(() => useAudioPlayer());

    expect(result.current.playedSongs).toEqual({});
    expect(result.current.currentlyPlaying).toBe(null);
    expect(result.current.pageDurations).toEqual({});
    expect(result.current.audioDurations).toEqual({});
  });

  test('handlePlay updates state correctly', () => {
    const { result } = renderHook(() => useAudioPlayer());

    act(() => {
      result.current.handlePlay(0);
    });

    expect(result.current.currentlyPlaying).toBe(0);
    expect(result.current.playedSongs[0]).toBe(true);
  });

  test('handleNext advances to next song', () => {
    const { result } = renderHook(() => useAudioPlayer());
    const mockAudioFiles = ['song1.mp3', 'song2.mp3', 'song3.mp3'];

    act(() => {
      result.current.handlePlay(0);
    });

    act(() => {
      result.current.handleNext(mockAudioFiles);
    });

    expect(result.current.currentlyPlaying).toBe(1);
    expect(result.current.playedSongs[1]).toBe(true);
  });

  test('handleNext stops playing when at end', () => {
    const { result } = renderHook(() => useAudioPlayer());
    const mockAudioFiles = ['song1.mp3', 'song2.mp3'];

    act(() => {
      result.current.handlePlay(1); // Start at last song
    });

    act(() => {
      result.current.handleNext(mockAudioFiles);
    });

    expect(result.current.currentlyPlaying).toBe(null);
  });

  test('handlePrev goes to previous song', () => {
    const { result } = renderHook(() => useAudioPlayer());

    act(() => {
      result.current.handlePlay(1);
    });

    act(() => {
      result.current.handlePrev();
    });

    expect(result.current.currentlyPlaying).toBe(0);
    expect(result.current.playedSongs[0]).toBe(true);
  });

  test('handlePrev does nothing at first song', () => {
    const { result } = renderHook(() => useAudioPlayer());

    act(() => {
      result.current.handlePlay(0);
    });

    act(() => {
      result.current.handlePrev();
    });

    expect(result.current.currentlyPlaying).toBe(0);
  });

  test('handleLoadedMetadata updates audio durations', () => {
    const { result } = renderHook(() => useAudioPlayer());

    act(() => {
      result.current.handleLoadedMetadata(0, 1, 120.5);
    });

    expect(result.current.audioDurations['0-1']).toBe(120.5);
  });

  test('setIsPlaying updates currently playing state', () => {
    const { result } = renderHook(() => useAudioPlayer());

    act(() => {
      result.current.setIsPlaying(true, 2);
    });

    expect(result.current.currentlyPlaying).toBe(2);

    act(() => {
      result.current.setIsPlaying(false, 2);
    });

    expect(result.current.currentlyPlaying).toBe(null);
  });

  test('setIsPlaying does not change state for different index', () => {
    const { result } = renderHook(() => useAudioPlayer());

    act(() => {
      result.current.handlePlay(1);
    });

    act(() => {
      result.current.setIsPlaying(false, 2); // Different index
    });

    expect(result.current.currentlyPlaying).toBe(1); // Should remain unchanged
  });

  test('handleNext does not play when audio files array is empty', () => {
    const { result } = renderHook(() => useAudioPlayer());
    const emptyAudioFiles = [];

    act(() => {
      result.current.handleNext(emptyAudioFiles);
    });

    expect(result.current.currentlyPlaying).toBe(null);
    expect(result.current.playedSongs).toEqual({});
  });

  test('handleNext stops playing when audio files becomes empty', () => {
    const { result } = renderHook(() => useAudioPlayer());
    const mockAudioFiles = ['song1.mp3', 'song2.mp3'];
    const emptyAudioFiles = [];

    // Start playing
    act(() => {
      result.current.handlePlay(0);
    });

    expect(result.current.currentlyPlaying).toBe(0);

    // Call handleNext with empty array
    act(() => {
      result.current.handleNext(emptyAudioFiles);
    });

    expect(result.current.currentlyPlaying).toBe(null);
  });

  test('handleNext does not play when audio files is null or undefined', () => {
    const { result } = renderHook(() => useAudioPlayer());

    act(() => {
      result.current.handleNext(null);
    });

    expect(result.current.currentlyPlaying).toBe(null);

    act(() => {
      result.current.handleNext(undefined);
    });

    expect(result.current.currentlyPlaying).toBe(null);
  });
});