import { afterEach, describe, expect, test, vi } from 'vitest';
import type { TrackRef } from '$lib/api/types';
import { audioLoader, setAudioLoader, __resetAudioLoader } from './audioLoader';

const sampleTrack: TrackRef = {
  id: 't1',
  title: 'Sample',
  album_id: 'a1',
  album_title: 'Album',
  artist_id: 'ar1',
  artist_name: 'Artist',
  duration_sec: 180,
  stream_url: '/api/tracks/t1/stream'
};

afterEach(() => {
  __resetAudioLoader();
});

describe('audioLoader', () => {
  test('default resolve returns the track stream_url', () => {
    expect(audioLoader.resolve(sampleTrack)).toBe('/api/tracks/t1/stream');
  });

  test('default prefetch is a no-op (does not throw)', () => {
    expect(() => audioLoader.prefetch?.(sampleTrack)).not.toThrow();
  });

  test('setAudioLoader swaps the resolver', () => {
    setAudioLoader({
      resolve: (t) => `blob:cached-${t.id}`
    });
    expect(audioLoader.resolve(sampleTrack)).toBe('blob:cached-t1');
  });

  test('setAudioLoader swaps the prefetch hook', () => {
    const spy = vi.fn();
    setAudioLoader({
      resolve: (t) => t.stream_url,
      prefetch: spy
    });
    audioLoader.prefetch?.(sampleTrack);
    expect(spy).toHaveBeenCalledWith(sampleTrack);
  });

  test('__resetAudioLoader restores the default', () => {
    setAudioLoader({ resolve: () => 'blob:swapped' });
    expect(audioLoader.resolve(sampleTrack)).toBe('blob:swapped');
    __resetAudioLoader();
    expect(audioLoader.resolve(sampleTrack)).toBe('/api/tracks/t1/stream');
  });
});
