import { describe, it, expect } from 'vitest';
import { lookupLinksFor, bookLinksFor } from './links';
import type { Citation, RefMetadata } from './types';

const cite = (kind: Citation['kind'], value: string): Citation => ({
  kind,
  value,
  raw: value,
});

describe('lookupLinksFor', () => {
  it('builds a DOI resolver link', () => {
    const l = lookupLinksFor(cite('doi', '10.1038/nphys1170'));
    expect(l.doi).toBe('https://doi.org/10.1038%2Fnphys1170');
  });

  it('builds an arXiv abstract link', () => {
    const l = lookupLinksFor(cite('arxiv', '1706.03762'));
    expect(l.arxiv).toBe('https://arxiv.org/abs/1706.03762');
  });

  it('points openLibrary at the ISBN page for isbn citations', () => {
    const l = lookupLinksFor(cite('isbn', '9780134685991'));
    expect(l.openLibrary).toBe('https://openlibrary.org/isbn/9780134685991');
  });

  it('always includes wikipedia/googleBooks search links', () => {
    const l = lookupLinksFor(cite('author-year', 'Vaswani (2017)'));
    expect(l.wikipedia).toContain(
      'https://en.wikipedia.org/wiki/Special:Search?search=',
    );
    expect(l.googleBooks).toContain('https://www.google.com/search?tbm=bks&q=');
  });

  it('always includes annasArchive and libgen search links', () => {
    const l = lookupLinksFor(cite('doi', '10.1/x'));
    expect(l.annasArchive).toContain('https://annas-archive.org/search?q=');
    expect(l.libgen).toContain('https://libgen.is/search.php?req=');
  });

  it('prefers resolved metadata title for the search query, URL-encoded', () => {
    const meta: RefMetadata = {
      title: 'Attention Is All You Need',
      source: 'Crossref',
    };
    const l = lookupLinksFor(cite('arxiv', '1706.03762'), meta);
    const q = encodeURIComponent('Attention Is All You Need');
    expect(l.wikipedia).toContain(q);
    expect(l.annasArchive).toContain(q);
  });

  it('falls back to the citation value when no metadata title', () => {
    const l = lookupLinksFor(cite('author-year', 'Smith et al. (2021)'));
    const q = encodeURIComponent('Smith et al. (2021)');
    expect(l.googleBooks).toContain(q);
  });
});

describe('bookLinksFor', () => {
  it('builds the full search set from a free-text query (no doi/arxiv)', () => {
    const l = bookLinksFor('Introduction to Algorithms');
    const q = encodeURIComponent('Introduction to Algorithms');
    expect(l.doi).toBeUndefined();
    expect(l.arxiv).toBeUndefined();
    expect(l.openLibrary).toBe(`https://openlibrary.org/search?q=${q}`);
    expect(l.wikipedia).toContain(q);
    expect(l.googleBooks).toContain(q);
    expect(l.annasArchive).toContain(q);
    expect(l.libgen).toContain(q);
  });

  it('URL-encodes special characters', () => {
    const l = bookLinksFor('C&A: a/b test');
    expect(l.libgen).toContain(encodeURIComponent('C&A: a/b test'));
    expect(l.libgen).not.toContain(' ');
  });
});
