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

import {
  ExtractRequestSchema,
  BatchExtractRequestSchema,
  ExtractionExampleSchema,
  ExtractionResultSchema,
} from './types.js';

describe('ExtractionExampleSchema', () => {
  it('accepts valid example', () => {
    const result = ExtractionExampleSchema.safeParse({
      text: 'John said ship by Friday',
      extractions: [{ extraction_class: 'deadline', extraction_text: 'ship by Friday' }],
    });
    expect(result.success).toBe(true);
  });

  it('rejects empty text', () => {
    const result = ExtractionExampleSchema.safeParse({
      text: '',
      extractions: [],
    });
    expect(result.success).toBe(false);
  });

  it('accepts extractions with attributes', () => {
    const result = ExtractionExampleSchema.safeParse({
      text: 'test',
      extractions: [
        {
          extraction_class: 'emotion',
          extraction_text: 'stressed',
          attributes: { valence: 'negative' },
        },
      ],
    });
    expect(result.success).toBe(true);
  });
});

describe('ExtractionResultSchema', () => {
  it('accepts result with offsets', () => {
    const result = ExtractionResultSchema.safeParse({
      extraction_class: 'action_item',
      extraction_text: 'call the dentist',
      start_offset: 10,
      end_offset: 26,
    });
    expect(result.success).toBe(true);
  });

  it('accepts result without optional fields', () => {
    const result = ExtractionResultSchema.safeParse({
      extraction_class: 'topic',
      extraction_text: 'meeting',
    });
    expect(result.success).toBe(true);
  });
});

describe('ExtractRequestSchema', () => {
  it('accepts minimal valid request', () => {
    const result = ExtractRequestSchema.safeParse({
      text: 'Hello world',
    });
    expect(result.success).toBe(true);
  });

  it('accepts full request with all options', () => {
    const result = ExtractRequestSchema.safeParse({
      text: 'John said ship by Friday. Sarah will test.',
      taskId: 'transcript-extraction',
      modelId: 'gemini-2.5-flash',
      examples: [
        {
          text: 'example text',
          extractions: [{ extraction_class: 'person', extraction_text: 'John' }],
        },
      ],
      options: {
        extractionPasses: 2,
        maxWorkers: 5,
        maxCharBuffer: 1000,
      },
      productId: 'lysnrai',
    });
    expect(result.success).toBe(true);
  });

  it('rejects empty text', () => {
    const result = ExtractRequestSchema.safeParse({ text: '' });
    expect(result.success).toBe(false);
  });

  it('rejects text exceeding 50,000 chars', () => {
    const result = ExtractRequestSchema.safeParse({
      text: 'a'.repeat(50_001),
    });
    expect(result.success).toBe(false);
  });

  it('rejects invalid options', () => {
    const result = ExtractRequestSchema.safeParse({
      text: 'test',
      options: { extractionPasses: 10 },
    });
    expect(result.success).toBe(false);
  });
});

describe('BatchExtractRequestSchema', () => {
  it('accepts valid batch', () => {
    const result = BatchExtractRequestSchema.safeParse({
      inputs: [{ text: 'first document' }, { text: 'second document', taskId: 'triage' }],
    });
    expect(result.success).toBe(true);
  });

  it('rejects empty inputs', () => {
    const result = BatchExtractRequestSchema.safeParse({ inputs: [] });
    expect(result.success).toBe(false);
  });

  it('rejects batch exceeding 50 inputs', () => {
    const inputs = Array.from({ length: 51 }, (_, i) => ({
      text: `document ${i}`,
    }));
    const result = BatchExtractRequestSchema.safeParse({ inputs });
    expect(result.success).toBe(false);
  });
});
