// Wikimedia Commons client for artist images.
// Uses the MediaWiki API to search for and fetch artist images.
// No API key required; polite rate limit (~250ms) enforced via http base.

import { integrationsConfig, WikimediaConfig } from './config.js';
import { buildUserAgent, requestJson, HttpError } from './http.js';

interface WikimediaSearchResult {
  title?: string;
  pageid?: number;
  thumbnail?: { source?: string; width?: number; height?: number };
}

interface WikimediaSearchResponse {
  query?: {
    search?: WikimediaSearchResult[];
  };
}

interface WikimediaImageInfoResponse {
  query?: {
    pages?: {
      [pageId: string]: {
        imageinfo?: { url?: string; thumburl?: string; width?: number; height?: number }[];
      };
    };
  };
}

export class WikimediaClient {
  private readonly cfg: WikimediaConfig;
  private readonly userAgent: string;

  constructor(cfg: WikimediaConfig = integrationsConfig.wikimedia) {
    this.cfg = cfg;
    this.userAgent = buildUserAgent(integrationsConfig.musicbrainz.contact);
  }

  private async get<T>(path: string): Promise<T> {
    return requestJson<T>(`${this.cfg.baseUrl}${path}`, {
      userAgent: this.userAgent,
      minIntervalMs: this.cfg.minIntervalMs,
    });
  }

  /**
   * Search Wikimedia Commons for an artist image and return the best available
   * thumbnail URL (preferring larger sizes), or null on miss/error.
   */
  async getArtistImageUrl(artistName: string): Promise<string | null> {
    if (artistName.trim() === '') return null;

    try {
      // Search for the artist on Wikimedia Commons
      const searchQs = new URLSearchParams({
        action: 'query',
        list: 'search',
        srsearch: `${artistName} artist`,
        srnamespace: '6', // File namespace
        srlimit: '5',
        format: 'json',
      });
      const searchPath = `/w/api.php?${searchQs.toString()}`;
      const searchData = await this.get<WikimediaSearchResponse>(searchPath);

      const results = searchData.query?.search ?? [];
      if (results.length === 0) return null;

      // Get image info for the first few results to find the best thumbnail
      const pageIds = results.slice(0, 3).map((r) => r.pageid).filter((id): id is number => id !== undefined);
      if (pageIds.length === 0) return null;

      const imageQs = new URLSearchParams({
        action: 'query',
        prop: 'imageinfo',
        iiprop: 'url|thumburl|width|height',
        iiurlwidth: '300',
        iiurlheight: '300',
        pageids: pageIds.join('|'),
        format: 'json',
      });
      const imagePath = `/w/api.php?${imageQs.toString()}`;
      const imageData = await this.get<WikimediaImageInfoResponse>(imagePath);

      const pages = imageData.query?.pages ?? {};
      for (const pageId of pageIds) {
        const page = pages[pageId.toString()];
        if (page?.imageinfo?.[0]?.thumburl) {
          return page.imageinfo[0].thumburl;
        }
        if (page?.imageinfo?.[0]?.url) {
          return page.imageinfo[0].url;
        }
      }
      return null;
    } catch (err) {
      if (err instanceof HttpError && err.status === 404) return null;
      console.warn('[Wikimedia] getArtistImageUrl failed:', (err as Error).message);
      return null;
    }
  }
}