import { describe, it, expect, vi, beforeEach } from 'vitest';
import {
  getCoverProviders,
  updateCoverProvider,
  testCoverProvider,
  type CoverProvider,
  type CoverProvidersResponse
} from './admin';

vi.mock('./client', () => ({
  api: { get: vi.fn(), post: vi.fn(), patch: vi.fn() }
}));

import { api } from './client';

describe('admin cover-sources API', () => {
  beforeEach(() => vi.clearAllMocks());

  it('getCoverProviders GETs the correct path', async () => {
    const sample: CoverProvidersResponse = {
      providers: [
        {
          id: 'mbcaa',
          display_name: 'Cover Art Archive',
          requires_api_key: false,
          supports: ['album_cover'],
          enabled: true,
          api_key_set: false,
          display_order: 0,
          testable: true
        }
      ],
      sources_version: 1
    };
    (api.get as unknown as ReturnType<typeof vi.fn>).mockResolvedValueOnce(sample);
    const got = await getCoverProviders();
    expect(api.get).toHaveBeenCalledWith('/api/admin/cover-sources');
    expect(got.providers[0].id).toBe('mbcaa');
    expect(got.sources_version).toBe(1);
  });

  it('updateCoverProvider PATCHes the right path with patch body', async () => {
    const patched: CoverProvider & { version_bumped: boolean } = {
      id: 'theaudiodb',
      display_name: 'TheAudioDB',
      requires_api_key: true,
      supports: ['album_cover', 'artist_thumb', 'artist_fanart'],
      enabled: true,
      api_key_set: true,
      display_order: 1,
      testable: true,
      version_bumped: false
    };
    (api.patch as unknown as ReturnType<typeof vi.fn>).mockResolvedValueOnce(patched);
    const got = await updateCoverProvider('theaudiodb', { api_key: 'mykey' });
    expect(api.patch).toHaveBeenCalledWith(
      '/api/admin/cover-sources/theaudiodb',
      { api_key: 'mykey' }
    );
    expect(got.api_key_set).toBe(true);
    expect(got.version_bumped).toBe(false);
  });

  it('updateCoverProvider with enabled toggle returns version_bumped: true', async () => {
    const patched: CoverProvider & { version_bumped: boolean } = {
      id: 'theaudiodb',
      display_name: 'TheAudioDB',
      requires_api_key: true,
      supports: ['album_cover', 'artist_thumb', 'artist_fanart'],
      enabled: false,
      api_key_set: false,
      display_order: 1,
      testable: true,
      version_bumped: true
    };
    (api.patch as unknown as ReturnType<typeof vi.fn>).mockResolvedValueOnce(patched);
    const got = await updateCoverProvider('theaudiodb', { enabled: false });
    expect(got.version_bumped).toBe(true);
    expect(got.enabled).toBe(false);
  });

  it('testCoverProvider POSTs to /test endpoint with empty body', async () => {
    (api.post as unknown as ReturnType<typeof vi.fn>).mockResolvedValueOnce({
      ok: true,
      duration_ms: 234
    });
    const got = await testCoverProvider('theaudiodb');
    expect(api.post).toHaveBeenCalledWith('/api/admin/cover-sources/theaudiodb/test', {});
    expect(got.ok).toBe(true);
    expect(got.duration_ms).toBe(234);
  });

  it('testCoverProvider returns ok=false with error string on failure', async () => {
    (api.post as unknown as ReturnType<typeof vi.fn>).mockResolvedValueOnce({
      ok: false,
      duration_ms: 12,
      error: 'connection refused'
    });
    const got = await testCoverProvider('theaudiodb');
    expect(got.ok).toBe(false);
    expect(got.error).toBe('connection refused');
  });
});
