import { describe, it, expect } from 'vitest';
import {
  buildExtractionPrompt,
  parseExtractionResponse,
  regexFallbackExtraction,
} from '../extraction.js';

describe('buildExtractionPrompt', () => {
  it('includes hall types in the prompt', () => {
    const prompt = buildExtractionPrompt('some content', {
      hallTypes: ['decisions', 'events', 'discoveries'],
    });
    expect(prompt).toContain('decisions, events, discoveries');
    expect(prompt).toContain('some content');
  });

  it('includes title when provided', () => {
    const prompt = buildExtractionPrompt('content', {
      title: 'My Note',
      hallTypes: ['decisions'],
    });
    expect(prompt).toContain('Title: My Note');
  });

  it('includes context when provided', () => {
    const prompt = buildExtractionPrompt('content', {
      context: 'Work brain',
      hallTypes: ['decisions'],
    });
    expect(prompt).toContain('Context: Work brain');
  });

  it('omits title/context when not provided', () => {
    const prompt = buildExtractionPrompt('content', {
      hallTypes: ['decisions'],
    });
    expect(prompt).not.toContain('Title:');
    expect(prompt).not.toContain('Context:');
  });
});

describe('parseExtractionResponse', () => {
  it('parses valid JSON array', () => {
    const input = JSON.stringify([
      { hall: 'decisions', content: 'Use TypeScript', roomSlug: 'tech', entities: ['TypeScript'] },
    ]);
    const result = parseExtractionResponse(input);
    expect(result).toHaveLength(1);
    expect(result[0].hall).toBe('decisions');
    expect(result[0].content).toBe('Use TypeScript');
    expect(result[0].roomSlug).toBe('tech');
    expect(result[0].entities).toEqual(['TypeScript']);
  });

  it('handles JSON wrapped in code fences', () => {
    const input =
      '```json\n[{"hall":"events","content":"Released v2","roomSlug":"releases","entities":[]}]\n```';
    const result = parseExtractionResponse(input);
    expect(result).toHaveLength(1);
    expect(result[0].hall).toBe('events');
  });

  it('returns empty array for malformed JSON', () => {
    expect(parseExtractionResponse('not json at all')).toEqual([]);
  });

  it('returns empty array for empty string', () => {
    expect(parseExtractionResponse('')).toEqual([]);
  });

  it('filters out items missing required fields', () => {
    const input = JSON.stringify([{ hall: 'decisions', content: 'valid' }, { noHall: true }]);
    const result = parseExtractionResponse(input);
    expect(result).toHaveLength(1);
  });

  it('defaults roomSlug to general', () => {
    const input = JSON.stringify([{ hall: 'events', content: 'something' }]);
    const result = parseExtractionResponse(input);
    expect(result[0].roomSlug).toBe('general');
  });

  it('handles room_slug snake_case variant', () => {
    const input = JSON.stringify([{ hall: 'events', content: 'x', room_slug: 'my-room' }]);
    const result = parseExtractionResponse(input);
    expect(result[0].roomSlug).toBe('my-room');
  });
});

describe('regexFallbackExtraction', () => {
  it('extracts Decision: lines', () => {
    const result = regexFallbackExtraction('Decision: Use Cosmos DB for storage');
    expect(result).toHaveLength(1);
    expect(result[0].hall).toBe('decisions');
    expect(result[0].content).toContain('Use Cosmos DB');
  });

  it('extracts TODO: lines', () => {
    const result = regexFallbackExtraction('TODO: Fix the auth bug');
    expect(result).toHaveLength(1);
    expect(result[0].hall).toBe('decisions');
  });

  it('extracts Found: lines as discoveries', () => {
    const result = regexFallbackExtraction('Found: New API endpoint for search');
    expect(result).toHaveLength(1);
    expect(result[0].hall).toBe('discoveries');
  });

  it('extracts @mentions as entities', () => {
    const result = regexFallbackExtraction('Decision: @alice proposed the new schema');
    expect(result[0].entities).toContain('alice');
  });

  it('extracts #tags as entities', () => {
    const result = regexFallbackExtraction('Found: #typescript has better types');
    expect(result[0].entities).toContain('typescript');
  });

  it('returns empty array for plain text without patterns', () => {
    expect(regexFallbackExtraction('Just some random text here')).toEqual([]);
  });

  it('handles multiple patterns in multi-line content', () => {
    const content = `Decision: Adopt ESM
Found: Vitest is faster
TODO: Migrate tests`;
    const result = regexFallbackExtraction(content);
    expect(result).toHaveLength(3);
  });
});
