// Pure bibliography serialization: BibTeX and RIS. No network, no I/O.

import type { RefMetadata } from './types';

/** Serialize references to BibTeX. Handles missing fields and []. */
export function toBibtex(refs: RefMetadata[]): string {
  return refs.map((r, i) => bibEntry(r, i)).join('\n\n');
}

function bibEntry(r: RefMetadata, index: number): string {
  const type = r.authors && r.authors.length ? 'article' : 'misc';
  const key = bibKey(r, index);

  const fields: string[] = [];
  if (r.title) fields.push(`  title = {${brace(r.title)}}`);
  if (r.authors && r.authors.length) {
    fields.push(`  author = {${brace(r.authors.join(' and '))}}`);
  }
  if (r.year !== undefined) fields.push(`  year = {${r.year}}`);
  if (r.url) fields.push(`  url = {${brace(r.url)}}`);

  return `@${type}{${key},\n${fields.join(',\n')}\n}`;
}

function bibKey(r: RefMetadata, index: number): string {
  const first = r.authors && r.authors[0];
  if (first) {
    // Last token of the first author's name, alphanumerics only.
    const tokens = first.trim().split(/[\s,]+/);
    const surname = (tokens[tokens.length - 1] ?? first)
      .replace(/[^A-Za-z0-9]/g, '')
      .toLowerCase();
    if (surname) return `${surname}${r.year ?? ''}`;
  }
  return `ref${index}`;
}

/** Escape characters special to BibTeX brace-delimited values. */
function brace(s: string): string {
  // Inside `{...}` we still must escape a stray backslash and the braces.
  return s.replace(/\\/g, '\\\\').replace(/[{}]/g, (m) => `\\${m}`);
}

// ---------------------------------------------------------------------------
// RIS
// ---------------------------------------------------------------------------

/** Serialize references to RIS. Handles missing fields and []. */
export function toRis(refs: RefMetadata[]): string {
  return refs.map(risEntry).join('\n\n');
}

function risEntry(r: RefMetadata): string {
  const ty = r.authors && r.authors.length ? 'JOUR' : 'GEN';
  const lines: string[] = [`TY  - ${ty}`];
  if (r.title) lines.push(`TI  - ${r.title}`);
  if (r.authors) {
    for (const a of r.authors) lines.push(`AU  - ${a}`);
  }
  if (r.year !== undefined) lines.push(`PY  - ${r.year}`);
  if (r.url) lines.push(`UR  - ${r.url}`);
  lines.push('ER  - ');
  return lines.join('\n');
}
