import { beforeEach, describe, expect, it, vi } from 'vitest';

// In-memory KB the mocked db serves from.
const store = {
  topics: [],
  relations: [],
  content: new Map(),
};

vi.mock('../../../lib/db', () => ({
  getTopics: vi.fn(async () => store.topics),
  getRelations: vi.fn(async () => store.relations),
  getContent: vi.fn(async (id) => store.content.get(id) ?? null),
}));

import { buildKbContext } from '../rag';

beforeEach(() => {
  store.topics = [];
  store.relations = [];
  store.content = new Map();
});

describe('buildKbContext', () => {
  it('reports an empty graph', async () => {
    const { context, allTopics } = await buildKbContext('pensioen');
    expect(context).toMatch(/leeg/);
    expect(allTopics).toEqual([]);
  });

  it('injects deep content for a retrieved topic that is not named verbatim', async () => {
    store.topics = [
      { id: 'pensioenregeling', label: 'Pensioenregeling', type: 'concept', description: 'De beschikbare premieregeling.' },
      { id: 'onboarding-buddy', label: 'Onboarding Buddy', type: 'role', description: 'Begeleidt nieuwe medewerkers.' },
    ];
    store.content.set('pensioenregeling', {
      article: 'De premie is 10% van de pensioengrondslag; werkgever en werknemer betalen elk 50%.',
    });

    // "pensioen" is never a verbatim topic id/label, but the compound-word
    // matching should retrieve pensioenregeling and pull its article body in.
    const { context, retrievedTopics } = await buildKbContext('wat dekt mijn pensioen?');

    expect(retrievedTopics.map(t => t.id)).toContain('pensioenregeling');
    expect(context).toMatch(/DIEPERE INHOUD/);
    expect(context).toMatch(/10% van de pensioengrondslag/);
  });

  it('only includes relations whose endpoints are both in the selection', async () => {
    store.topics = [
      { id: 'pensioenregeling', label: 'Pensioenregeling', type: 'concept', description: 'De beschikbare premieregeling.' },
      { id: 'partnerpensioen', label: 'Partnerpensioen', type: 'concept', description: 'Uitkering aan de partner.' },
    ];
    store.relations = [
      { source: 'partnerpensioen', target: 'pensioenregeling', type: 'part_of' },
      { source: 'pensioenregeling', target: 'iets-anders', type: 'related_to' },
    ];

    const { context } = await buildKbContext('pensioen');
    expect(context).toMatch(/partnerpensioen --part_of--> pensioenregeling/);
    expect(context).not.toMatch(/iets-anders/);
  });
});
