import { renderHook, waitFor } from '@testing-library/react';
import { useAudioData } from '../useAudioData';
import { API_CONFIG } from '../../config/constants';

// Mock fetch
global.fetch = jest.fn() as jest.MockedFunction<typeof fetch>;

// Mock default songs
jest.mock('../../defaultSong.json', () => ({
  defaultSongs: ['song1.mp3', 'song2.mp3']
}));

describe('useAudioData', () => {
  afterEach(() => {
    jest.clearAllMocks();
  });

  test('fetches and processes audio data successfully', async () => {
    const mockResponse = {
      pages: [
        {
          name: 'test-page-1',
          audioFiles: ['file1.mp3', 'file2.mp3']
        },
        {
          name: 'test-page-2',
          useDefault: true
        }
      ]
    };

    (fetch as jest.MockedFunction<typeof fetch>).mockResolvedValueOnce({
      ok: true,
      json: async () => mockResponse
    } as Response);

    const { result } = renderHook(() => useAudioData());

    expect(result.current.isLoading).toBe(true);
    expect(result.current.error).toBe(null);

    await waitFor(() => {
      expect(result.current.isLoading).toBe(false);
    });

    expect(result.current.pages).toHaveLength(2);
    expect(result.current.pages[0]).toEqual(mockResponse.pages[0]);
    expect(result.current.pages[1].audioFiles).toEqual([
      'neon230817/test-page-2/song1.mp3',
      'neon230817/test-page-2/song2.mp3'
    ]);
    expect(result.current.error).toBe(null);
  });

  test('handles fetch error', async () => {
    (fetch as jest.MockedFunction<typeof fetch>).mockResolvedValueOnce({
      ok: false,
      status: 404
    } as Response);

    const { result } = renderHook(() => useAudioData());

    await waitFor(() => {
      expect(result.current.isLoading).toBe(false);
    });

    expect(result.current.pages).toEqual([]);
    expect(result.current.error).toContain('Error loading data');
  });

  test('handles network error', async () => {
    (fetch as jest.MockedFunction<typeof fetch>).mockRejectedValueOnce(new Error('Network error'));

    const { result } = renderHook(() => useAudioData());

    await waitFor(() => {
      expect(result.current.isLoading).toBe(false);
    });

    expect(result.current.pages).toEqual([]);
    expect(result.current.error).toContain('Network error');
  });

  test('calls correct API endpoint', async () => {
    (fetch as jest.MockedFunction<typeof fetch>).mockResolvedValueOnce({
      ok: true,
      json: async () => ({ pages: [] })
    } as Response);

    renderHook(() => useAudioData());

    expect(fetch).toHaveBeenCalledWith(API_CONFIG.jsonUrl);
  });
});