import { DbService } from './db.service.js';

export class ImageEnrichmentService {
  private sourcePriority: Record<string, number> = {
    cover_art_archive: 1,
    theaudiodb: 2,
    fanart: 3,
    deezer: 4,
    discogs: 5,
    lastfm: 6,
  };

  constructor(private db: DbService) {}

  // ---------------------------------------------------------------
  // Phase 4 — Fetch image candidates from all sources
  // ---------------------------------------------------------------
  async fetchImagesForArtist(artistId: string): Promise<number> {
    const artistRes = await this.db.pgClient.query<{ id: string; name: string; mbid: string | null; discogs_id: string | null }>(
      `SELECT id, name, mbid, discogs_id FROM artists WHERE id = $1`,
      [artistId]
    );
    const artist = artistRes.rows[0];
    if (!artist) return 0;

    const sources: { key: string; condition: string }[] = [
      { key: 'cover_art_archive', condition: artist.mbid ? 'mbid present' : 'no mbid' },
      { key: 'deezer', condition: 'always' },
      { key: 'discogs', condition: artist.discogs_id ? 'discogs_id present' : 'no discogs_id' },
      { key: 'lastfm', condition: 'always' },
    ];

    let count = 0;

    for (const src of sources) {
      const res = await this.db.pgClient.query(
        `INSERT INTO image_candidates (entity_type, entity_id, source, url, width)
         VALUES ('artist', $1, $2, NULL, NULL)
         ON CONFLICT (entity_type, entity_id, source) DO NOTHING
         RETURNING 1 AS ins`,
        [artistId, src.key]
      );
      if (res.rows.length > 0) count++;
    }

    return count;
  }

  async fetchImagesForAlbum(albumId: string): Promise<number> {
    const sources = ['cover_art_archive', 'itunes', 'deezer', 'discogs'];
    let count = 0;

    for (const source of sources) {
      const res = await this.db.pgClient.query(
        `INSERT INTO image_candidates (entity_type, entity_id, source, url, width)
         VALUES ('album', $1, $2, NULL, NULL)
         ON CONFLICT (entity_type, entity_id, source) DO NOTHING
         RETURNING 1 AS ins`,
        [albumId, source]
      );
      if (res.rows.length > 0) count++;
    }

    return count;
  }

  async selectBestImage(entityType: string, entityId: string): Promise<string | null> {
    const candidates = await this.db.pgClient.query<{ url: string; source: string; verified: boolean }>(
      `SELECT url, source, verified
       FROM image_candidates
       WHERE entity_type = $1 AND entity_id = $2 AND url IS NOT NULL
       ORDER BY
         CASE source
           WHEN 'cover_art_archive' THEN 1
           WHEN 'theaudiodb' THEN 2
           WHEN 'fanart' THEN 3
           WHEN 'deezer' THEN 4
           WHEN 'discogs' THEN 5
           WHEN 'lastfm' THEN 6
           ELSE 99
         END,
         verified DESC,
         width DESC NULLS LAST
       LIMIT 1`,
      [entityType, entityId]
    );

    const best = candidates.rows[0];
    if (!best) return null;

    if (entityType === 'artist') {
      await this.db.pgClient.query(
        `UPDATE artists SET image_path = $1 WHERE id = $2`,
        [best.url, entityId]
      );
    } else if (entityType === 'album') {
      await this.db.pgClient.query(
        `UPDATE albums SET artwork_id = $1 WHERE id = $2`,
        [best.url, entityId]
      );
    }

    return best.url;
  }
}
