// Centralised, typed configuration for the external-integration clients.
//
// Enrichment is best-effort: a missing required key must NOT crash the worker.
// Instead the owning client logs a one-time warning at construction and its
// methods short-circuit to null/[] (see musicbrainz.client.ts / lastfm.client.ts).

export interface MusicBrainzConfig {
  /** Base URL for the MusicBrainz web service v2. No trailing slash. */
  baseUrl: string;
  /**
   * Contact (email or URL) embedded in the required User-Agent. MusicBrainz
   * rejects/throttles requests without a meaningful UA. Empty if unset.
   */
  contact: string;
  /** Minimum interval between requests to the MB host (MB requires <=1 req/sec). */
  minIntervalMs: number;
}

export interface LastFmConfig {
  /** Base URL for the Last.fm 2.0 API. No trailing slash. */
  baseUrl: string;
  /** API key. Empty string when unconfigured -> client degrades to no-ops. */
  apiKey: string;
  /** Shared secret (only needed for authenticated/write calls; optional here). */
  sharedSecret: string;
  /** Minimum interval between requests to the Last.fm host. */
  minIntervalMs: number;
}

export interface DiscogsConfig {
  /** Base URL for the Discogs API. No trailing slash. */
  baseUrl: string;
  /** Personal access token. Empty string when unconfigured -> client degrades to no-ops. */
  token: string;
  /** Minimum interval between requests (Discogs allows ~60 req/min authenticated). */
  minIntervalMs: number;
}

export interface LrcLibConfig {
  /** Base URL for the LRCLib API. No trailing slash. */
  baseUrl: string;
  /** Minimum interval between requests (polite default; no key required). */
  minIntervalMs: number;
}

export interface CoverArtConfig {
  /** Base URL for the Cover Art Archive. No trailing slash. */
  baseUrl: string;
  /** Minimum interval between requests (polite default; no key required). */
  minIntervalMs: number;
}

export interface WikimediaConfig {
  /** Base URL for the Wikimedia API. No trailing slash. */
  baseUrl: string;
  /** Minimum interval between requests (polite default; no key required). */
  minIntervalMs: number;
}

export interface IntegrationsConfig {
  musicbrainz: MusicBrainzConfig;
  lastfm: LastFmConfig;
  discogs: DiscogsConfig;
  lrclib: LrcLibConfig;
  coverart: CoverArtConfig;
  wikimedia: WikimediaConfig;
}

function stripTrailingSlash(url: string): string {
  return url.replace(/\/+$/, '');
}

function env(name: string, fallback = ''): string {
  const v = process.env[name];
  return v && v.trim() !== '' ? v.trim() : fallback;
}

export const integrationsConfig: IntegrationsConfig = {
  musicbrainz: {
    baseUrl: stripTrailingSlash(
      env('MUSICBRAINZ_BASE_URL', 'https://musicbrainz.org/ws/2')
    ),
    contact: env('MUSICBRAINZ_CONTACT'),
    minIntervalMs: 1000,
  },
  lastfm: {
    baseUrl: stripTrailingSlash(
      env('LASTFM_BASE_URL', 'http://ws.audioscrobbler.com/2.0')
    ),
    apiKey: env('LASTFM_API_KEY'),
    sharedSecret: env('LASTFM_SHARED_SECRET'),
    minIntervalMs: 250,
  },
  discogs: {
    baseUrl: stripTrailingSlash(env('DISCOGS_BASE_URL', 'https://api.discogs.com')),
    token: env('DISCOGS_TOKEN'),
    // ~60 req/min authenticated -> ~1.1s between requests.
    minIntervalMs: 1100,
  },
  lrclib: {
    baseUrl: stripTrailingSlash(env('LRCLIB_BASE_URL', 'https://lrclib.net/api')),
    minIntervalMs: 250,
  },
  coverart: {
    baseUrl: stripTrailingSlash(env('COVERART_BASE_URL', 'https://coverartarchive.org')),
    minIntervalMs: 250,
  },
  wikimedia: {
    baseUrl: stripTrailingSlash(env('WIKIMEDIA_BASE_URL', 'https://commons.wikimedia.org')),
    minIntervalMs: 250,
  },
};
