import { describe, it, expect } from 'vitest';
import { glossary } from './glossary';
import type { Segment } from '../types';

const seg = (start: number, text: string, id?: string): Segment => ({
  id,
  start,
  end: start + 1,
  text,
});

describe('glossary', () => {
  it('returns [] for no segments', () => {
    expect(glossary([])).toEqual([]);
  });

  it('captures an "X is Y" definition pattern', () => {
    const segs = [
      seg(3, 'Backpropagation is an algorithm for training neural networks.', 's1'),
    ];
    const out = glossary(segs);
    const entry = out.find((e) => e.term.toLowerCase() === 'backpropagation');
    expect(entry).toBeDefined();
    expect(entry!.definition).toBe(
      'Backpropagation is an algorithm for training neural networks.',
    );
    expect(entry!.start).toBe(3);
    expect(entry!.segmentId).toBe('s1');
  });

  it('recognizes means / refers to / is defined as', () => {
    const segs = [
      seg(0, 'Entropy means the amount of disorder in a system.'),
      seg(1, 'A token refers to a unit of text.'),
      seg(2, 'Latency is defined as the delay before a transfer begins.'),
    ];
    const terms = glossary(segs).map((e) => e.term.toLowerCase());
    expect(terms).toContain('entropy');
    expect(terms).toContain('a token');
    expect(terms).toContain('latency');
  });

  it('dedupes by lowercased term, preferring the explicit definition', () => {
    const segs = [
      seg(0, 'Recursion is fun. Recursion appears again here as Recursion.'),
      seg(1, 'Recursion is when a function calls itself.', 'def'),
    ];
    const out = glossary(segs);
    const recursion = out.filter((e) => e.term.toLowerCase() === 'recursion');
    expect(recursion.length).toBe(1);
    expect(recursion[0]!.definition).toBe(
      'Recursion is when a function calls itself.',
    );
  });

  it('respects the max cap', () => {
    const segs = [
      seg(0, 'Apple is a fruit.'),
      seg(1, 'Banana is a fruit.'),
      seg(2, 'Cherry is a fruit.'),
    ];
    expect(glossary(segs, { max: 2 }).length).toBeLessThanOrEqual(2);
  });
});
