import { describe, expect, it } from 'vitest';
import { readFileSync } from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { loadFixture, runFixtureSuite } from '@rareindex/connectors/testing';
import { localMeta } from '../../api/_lib/local-meta.js';
import createConnector, { parseCategoryPage, parseResultsPage, parseSaleHeader } from './index.js';
import { parseAuctionDate, parseCoinGrade, realized } from '../_g5-numismatics-lib/index.js';
const dir = path.dirname(fileURLToPath(import.meta.url));
const connector = createConnector(localMeta(JSON.parse(readFileSync(path.join(dir, 'meta.json'), 'utf8'))));
const RESULTS = `
`;
const SALE = `
`;
describe('numisbids', () => {
runFixtureSuite(connector, it, expect);
it('parses the results page: only sales with a "Prices realized" link on NumisBids', () => {
const r = parseResultsPage(RESULTS);
expect(r).toEqual([{ sid: '11008', eventId: '14682', firm: 'CNG', title: 'Electronic Auction 616', subtitle: '1114 Lots of Ancient and World Coins', dayText: '2nd' }]);
});
it('parses the sale header, category list and paginated category page', () => {
const h = parseSaleHeader(SALE, '5000');
expect(h).not.toBeNull();
expect(h!.sale).toEqual({ sid: '5000', firm: 'Goudwisselkantoor Veilingen', title: 'Auction 1182 and 1183', dateText: '8,11 Oct 2021' });
expect(h!.hasPrices).toBe(true);
expect(h!.categories).toEqual([{ cid: '153040', name: 'Banknotes', count: 677 }, { cid: '153044', name: 'Medals', count: 191 }]);
const p = parseCategoryPage(SALE, h!.sale, h!.categories[0]!, 'https://www.numisbids.com/sale/5000/category/153040?pg=2');
expect(p.page).toBe(2);
expect(p.totalPages).toBe(7);
expect(p.lots.length).toBe(2);
expect(p.lots[0]).toMatchObject({ lotNumber: '101', estimateText: '50 EUR', realizedText: '70 EUR', image: 'https://media.numisbids.com/sales/hosted/gwk/1182/thumb00101.jpg', url: 'https://www.numisbids.com/sale/5000/lot/101' });
expect(p.lots[1]!.realizedText).toBeNull();
});
it('normalises sold lots as hammer sales in the printed currency, dated by the sale header', async () => {
const h = parseSaleHeader(SALE, '5000')!;
const payload = parseCategoryPage(SALE, h.sale, h.categories[0]!, 'u');
const out = await connector.normalize({ url: 'u', externalId: 'x', kind: 'sale', engine: 'firecrawl', fetchedAt: new Date('2026-09-08T00:00:00Z'), payload });
expect(out.length).toBe(1); // lot 102 unsold
const s = out[0]!;
if (s.kind !== 'sale') throw new Error('sale');
expect(s).toMatchObject({ price: 70, currency: 'EUR', buyerPremiumIncluded: false, lotNumber: '101', auctionHouse: 'Goudwisselkantoor Veilingen', isBundle: false });
expect(s.saleDate.toISOString()).toBe('2021-10-08T00:00:00.000Z');
expect(s.attributes.categorySlug).toBe('banknotes');
expect(s.attributes.country).toBe('NL');
expect(s.attributes.year).toBe(1953);
expect(s.grade).toMatchObject({ grader: 'pmg', grade: '66 EPQ' });
expect(s.attributes.identifiers.numisbids_lot).toBe('5000/101');
expect(s.attributes.metadata.estimate).toBe(50);
});
it('helpers: dates, prices, grades', () => {
expect(parseAuctionDate('2 Sep 2026')?.toISOString()).toBe('2026-09-02T00:00:00.000Z');
expect(parseAuctionDate('8,11 Oct 2021')?.toISOString()).toBe('2021-10-08T00:00:00.000Z');
expect(parseAuctionDate('7-11 Sep 2026')?.toISOString()).toBe('2026-09-07T00:00:00.000Z');
expect(realized('160 USD')).toEqual({ amount: 160, currency: 'USD' });
expect(realized("CHF 1'200")).toEqual({ amount: 1200, currency: 'CHF' });
expect(realized('--')).toBeNull();
expect(realized('W/D')).toBeNull();
expect(parseCoinGrade('1881-S Morgan Dollar PCGS MS65+ CAC #12345678')).toMatchObject({ grader: 'pcgs', grade: 'MS65+', qualifier: 'CAC', certificationNumber: '12345678' });
expect(parseCoinGrade('NGC AU 58 1911 Sovereign')).toMatchObject({ grader: 'ngc', grade: 'AU58' });
expect(parseCoinGrade('Kings of Mercia, Coenwulf Penny, good very fine')).toMatchObject({ grader: null, grade: null, conditionRaw: 'good very fine' });
});
it('fixture lots normalise to hammer sales in USD', async () => {
const out = await connector.normalize(loadFixture('numisbids', 'category-page-celtic').raw);
expect(out.length).toBe(14);
for (const r of out) if (r.kind === 'sale') expect(r).toMatchObject({ currency: 'USD', buyerPremiumIncluded: false, auctionHouse: 'Classical Numismatic Group, Inc.' });
const fx = loadFixture('numisbids', 'category-page-paginated');
expect((fx.raw.payload as { totalPages: number }).totalPages).toBe(3);
});
});