import { beforeEach, describe, expect, it, vi } from 'vitest';
import {
  createAudioFile,
  deleteAudioFile,
  listAudioFiles,
} from '@/shared/api/audioFiles';
import { apiRequest } from '@/shared/api/httpClient';
import type { ApiListResponse } from '@/shared/types/api';
import type { AudioFileDto } from '@/shared/types/audioFiles';

vi.mock('@/shared/api/httpClient', () => ({
  apiRequest: vi.fn(),
}));

const apiRequestMock = vi.mocked(apiRequest);

describe('audioFiles API', () => {
  beforeEach(() => {
    apiRequestMock.mockReset();
  });

  describe('listAudioFiles', () => {
    it('fetches all audio files', async () => {
      const response: ApiListResponse<AudioFileDto> = {
        rows: [
          {
            id: 'audio-1',
            title: 'Bell Sound',
            kind: 'file',
            url: '/uploads/bell.mp3',
            recipe: null,
            is_default: false,
            organizationId: 'org-1',
            campusId: 'campus-1',
            createdAt: '2024-01-01T00:00:00Z',
            updatedAt: '2024-01-01T00:00:00Z',
          },
          {
            id: 'audio-2',
            title: 'Chime Recipe',
            kind: 'recipe',
            url: null,
            recipe: {
              voices: [
                {
                  waveform: 'sine',
                  notes: [{ freq: 440, startAt: 0, duration: 0.5, gain: 0.8 }],
                },
              ],
            },
            is_default: true,
            organizationId: null,
            campusId: null,
            createdAt: '2024-01-01T00:00:00Z',
            updatedAt: '2024-01-01T00:00:00Z',
          },
        ],
        count: 2,
      };
      apiRequestMock.mockResolvedValueOnce(response);

      await expect(listAudioFiles()).resolves.toEqual(response);

      expect(apiRequestMock).toHaveBeenCalledWith('/audio_files');
    });
  });

  describe('createAudioFile', () => {
    it('creates a new audio file', async () => {
      const created: AudioFileDto = {
        id: 'audio-new',
        title: 'New Sound',
        kind: 'url',
        url: 'https://example.com/sound.mp3',
        recipe: null,
        is_default: false,
        organizationId: 'org-1',
        campusId: 'campus-1',
        createdAt: '2024-01-15T10:00:00Z',
        updatedAt: '2024-01-15T10:00:00Z',
      };
      apiRequestMock.mockResolvedValueOnce(created);

      await expect(
        createAudioFile({
          kind: 'url',
          title: 'New Sound',
          url: 'https://example.com/sound.mp3',
        }),
      ).resolves.toEqual(created);

      expect(apiRequestMock).toHaveBeenCalledWith('/audio_files', {
        method: 'POST',
        body: {
          data: {
            kind: 'url',
            title: 'New Sound',
            url: 'https://example.com/sound.mp3',
          },
        },
      });
    });
  });

  describe('deleteAudioFile', () => {
    it('deletes an audio file', async () => {
      apiRequestMock.mockResolvedValueOnce(true);

      await expect(deleteAudioFile('audio-1')).resolves.toBe(true);

      expect(apiRequestMock).toHaveBeenCalledWith('/audio_files/audio-1', {
        method: 'DELETE',
      });
    });
  });
});
