// TheAudioDB client for artist images.
// API: https://www.theaudiodb.com/api_guide.php
// Free tier: 2 requests/second, no key required for basic use.
// With API key: higher limits.

import { requestJson } from './http.js';

interface AudioDbArtist {
  idArtist: string;
  strArtist: string;
  strArtistThumb?: string;
  strArtistBanner?: string;
  strArtistFanart?: string;
  strArtistLogo?: string;
  strArtistClearart?: string;
  strArtistWideThumb?: string;
}

interface AudioDbResponse {
  artists?: AudioDbArtist[];
}

export class TheAudioDbClient {
  private readonly baseUrl = 'https://www.theaudiodb.com/api/v1/json';
  private readonly apiKey: string;
  private readonly userAgent = 'muzick/0.1';

  constructor(apiKey?: string) {
    // Free tier uses '1' as key, paid tiers get custom keys
    this.apiKey = apiKey || process.env.THEAUDIO_DB_API_KEY || '1';
  }

  /**
   * Search for artist by name.
   */
  async searchArtist(name: string): Promise<AudioDbArtist | null> {
    const url = `${this.baseUrl}/${this.apiKey}/search.php?s=${encodeURIComponent(name)}`;

    try {
      const data = await requestJson<AudioDbResponse>(url, {
        userAgent: this.userAgent,
        minIntervalMs: 500, // 2 req/sec limit
      });

      return data.artists?.[0] ?? null;
    } catch (err) {
      console.warn('[TheAudioDB] searchArtist failed:', (err as Error).message);
    }
    return null;
  }

  /**
   * Get artist by MusicBrainz ID.
   */
  async getArtistByMbid(mbid: string): Promise<AudioDbArtist | null> {
    const url = `${this.baseUrl}/${this.apiKey}/artist-mb.php?i=${encodeURIComponent(mbid)}`;

    try {
      const data = await requestJson<AudioDbResponse>(url, {
        userAgent: this.userAgent,
        minIntervalMs: 500,
      });

      return data.artists?.[0] ?? null;
    } catch (err) {
      console.warn('[TheAudioDB] getArtistByMbid failed:', (err as Error).message);
    }
    return null;
  }

  /**
   * Get the best available artist image.
   * Priority: thumb > fanart > banner > logo > clearart > wide thumb
   */
  async getBestArtistImage(mbid: string): Promise<string | null> {
    // Try by MBID first (most accurate)
    let artist = await this.getArtistByMbid(mbid);
    
    // Fallback: search by name would need the name, which we don't have here
    // Caller should handle name-based fallback
    
    if (!artist) return null;

    return (
      artist.strArtistThumb ??
      artist.strArtistFanart ??
      artist.strArtistBanner ??
      artist.strArtistLogo ??
      artist.strArtistClearart ??
      artist.strArtistWideThumb ??
      null
    );
  }
}