import { describe, it, expect } from 'vitest';
import { generatePreview, computeStats } from './preview';
import type { ScreenplayElement } from '../screenplay/types';

const sampleElements: ScreenplayElement[] = [
  { id: 'e1', type: 'sceneHeading', content: 'INT. COFFEE SHOP - DAY' },
  { id: 'e2', type: 'action', content: 'A bustling coffee shop.\nJESSICA sits alone.' },
  { id: 'e3', type: 'character', content: 'Jessica' },
  { id: 'e4', type: 'dialogue', content: 'I need to make a decision.' },
  { id: 'e5', type: 'parenthetical', content: 'to herself' },
  { id: 'e6', type: 'dialogue', content: 'There is no other option.' },
  { id: 'e7', type: 'transition', content: 'CUT TO:' },
  { id: 'e8', type: 'sceneHeading', content: 'EXT. PARK - NIGHT' },
  { id: 'e9', type: 'action', content: 'The park is empty.' },
  { id: 'e10', type: 'character', content: 'Marcus' },
  { id: 'e11', type: 'dialogue', content: 'She never came back.' },
];

describe('generatePreview', () => {
  it('generates formatted preview text', () => {
    const result = generatePreview(sampleElements);
    expect(result.text).toContain('INT. COFFEE SHOP - DAY');
    expect(result.text).toContain('JESSICA');
  });

  it('applies uppercase to scene headings', () => {
    const result = generatePreview(sampleElements);
    expect(result.text).toContain('INT. COFFEE SHOP - DAY');
  });

  it('applies uppercase to character cues', () => {
    const result = generatePreview(sampleElements);
    expect(result.text).toContain('JESSICA');
    expect(result.text).toContain('MARCUS');
  });

  it('preserves dialogue case', () => {
    const result = generatePreview(sampleElements);
    expect(result.text).toContain('I need to make a decision.');
  });

  it('includes stats', () => {
    const result = generatePreview(sampleElements);
    expect(result.stats.totalElements).toBe(sampleElements.length);
    expect(result.stats.sceneCount).toBe(2);
    expect(result.stats.characterCount).toBe(2);
    expect(result.stats.transitionCount).toBe(1);
  });

  it('respects maxLines option', () => {
    const result = generatePreview(sampleElements, { maxLines: 5 });
    expect(result.text).toContain('... (truncated)');
  });

  it('includes page count when requested', () => {
    const result = generatePreview(sampleElements, { pageCount: true });
    expect(result.text).toContain('Estimated length:');
    expect(result.text).toContain('pages');
  });

  it('uses standard template by default', () => {
    const result = generatePreview(sampleElements);
    expect(result.stats.totalElements).toBeGreaterThan(0);
  });

  it('supports sitcom template', () => {
    const result = generatePreview(sampleElements, { template: 'sitcom' });
    expect(result.stats.totalElements).toBeGreaterThan(0);
  });

  it('handles empty elements', () => {
    const result = generatePreview([]);
    expect(result.text).toBe('');
    expect(result.stats.totalElements).toBe(0);
  });
});

describe('computeStats', () => {
  it('counts all element types', () => {
    const stats = computeStats(sampleElements);
    expect(stats.totalElements).toBe(11);
    expect(stats.sceneCount).toBe(2);
    expect(stats.actionCount).toBe(3);
    expect(stats.characterCount).toBe(2);
    expect(stats.dialogueCount).toBe(3);
    expect(stats.parentheticalCount).toBe(1);
    expect(stats.transitionCount).toBe(1);
  });

  it('estimates page count', () => {
    const stats = computeStats(sampleElements);
    expect(stats.estimatedPages).toBeGreaterThan(0);
    expect(stats.totalPages).toBe(stats.estimatedPages);
  });

  it('handles empty elements', () => {
    const stats = computeStats([]);
    expect(stats.totalElements).toBe(0);
    expect(stats.estimatedPages).toBe(0);
  });

  it('counts multi-line action correctly', () => {
    const elements: ScreenplayElement[] = [
      { id: 'e1', type: 'action', content: 'Line one.\nLine two.\nLine three.' },
    ];
    const stats = computeStats(elements);
    expect(stats.actionCount).toBe(3);
  });
});
