import { describe, expect, it, vi } from 'vitest';
import { DiscoveryService } from './discovery.service.js';
import type { DbService } from './db.service.js';

function makeDb() {
  const query = vi.fn();
  return {
    pgClient: { query },
    getListenerBeliefs: vi.fn(),
    upsertClaim: vi.fn().mockResolvedValue('claim-id'),
  } as unknown as DbService;
}

describe('DiscoveryService System E provenance', () => {
  it('writes graph-walk claims against discovery_candidate using registered graph provenance', async () => {
    const db = makeDb();
    (db.getListenerBeliefs as any).mockResolvedValue([
      { entity_id: '11111111-1111-1111-1111-111111111111', value: 0.8 },
    ]);
    (db.pgClient.query as any)
      .mockResolvedValueOnce({ rows: [{ candidate_artist_id: '22222222-2222-2222-2222-222222222222' }] })
      .mockResolvedValueOnce({ rows: [{ id: '33333333-3333-3333-3333-333333333333' }] });

    await new DiscoveryService(db).walkGraphForDiscovery('00000000-0000-0000-0000-000000000000');

    expect(db.upsertClaim).toHaveBeenCalledWith(expect.objectContaining({
      subject_type: 'discovery_candidate',
      source: 'graph_exploration',
    }));
  });

  it('does not queue artist-only graph candidates without a vetted acquisition URL', async () => {
    const db = makeDb();
    (db.pgClient.query as any)
      .mockResolvedValueOnce({ rows: [{ id: 'candidate-1', notes: { discovery_source: 'graph_exploration' } }] })
      .mockResolvedValueOnce({ rows: [{ cnt: 0 }] })
      .mockResolvedValueOnce({ rows: [{ object_id: 'artist-1', fused_value: 0.7 }] })
      .mockResolvedValueOnce({ rows: [] });

    const result = await new DiscoveryService(db).evalCandidates('00000000-0000-0000-0000-000000000000');

    expect(result).toEqual([{
      candidateId: 'candidate-1', shouldAcquire: false, reason: 'awaiting resolved acquisition source',
    }]);
    expect((db.pgClient.query as any).mock.calls.at(-1)[0]).toContain("status = 'awaiting_resolution'");
  });
});
