import { describe, it, expect, beforeEach } from 'vitest';
import { ExportManager } from './manager';
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.' },
  { id: 'e3', type: 'character', content: 'Jessica' },
  { id: 'e4', type: 'dialogue', content: 'Hello there.' },
  { id: 'e5', type: 'transition', content: 'CUT TO:' },
];

describe('ExportManager', () => {
  let manager: ExportManager;

  beforeEach(() => {
    manager = new ExportManager();
  });

  describe('getAvailableFormats', () => {
    it('returns all registered formats', () => {
      const formats = manager.getAvailableFormats();
      expect(formats).toContain('fountain');
      expect(formats).toContain('fdx');
      expect(formats).toContain('pdf');
      expect(formats).toContain('screenplay-pro');
    });
  });

  describe('export', () => {
    it('exports to fountain', () => {
      const result = manager.export(sampleElements, { format: 'fountain', title: 'Test' });
      expect(result.format).toBe('fountain');
      expect(result.data).toContain('# INT. COFFEE SHOP - DAY');
    });

    it('exports to fdx', () => {
      const result = manager.export(sampleElements, { format: 'fdx', title: 'Test' });
      expect(result.format).toBe('fdx');
      expect(result.data).toContain('<FDX');
    });

    it('exports to pdf', () => {
      const result = manager.export(sampleElements, { format: 'pdf', title: 'Test' });
      expect(result.format).toBe('pdf');
      expect(result.data).toContain('<!DOCTYPE html>');
    });

    it('exports to screenplay-pro', () => {
      const result = manager.export(sampleElements, { format: 'screenplay-pro', title: 'Test' });
      expect(result.format).toBe('screenplay-pro');
      expect(result.data).toContain('[HEADER]');
    });
  });

  describe('batchExport', () => {
    it('exports to multiple formats', () => {
      const result = manager.batchExport(sampleElements, ['fountain', 'fdx', 'pdf'], {
        title: 'Batch Test',
        author: 'Jane Doe',
      });
      expect(result.results).toHaveLength(3);
      expect(result.errors).toHaveLength(0);
      expect(result.formats).toEqual(['fountain', 'fdx', 'pdf']);
    });

    it('handles partial failures gracefully', () => {
      const result = manager.batchExport(sampleElements, ['fountain', 'fdx'], {});
      expect(result.results.length).toBeGreaterThanOrEqual(0);
    });

    it('exports all four formats', () => {
      const result = manager.batchExport(sampleElements, [
        'fountain',
        'fdx',
        'pdf',
        'screenplay-pro',
      ]);
      expect(result.results).toHaveLength(4);
      expect(result.errors).toHaveLength(0);
    });

    it('applies base options to all exports', () => {
      const result = manager.batchExport(sampleElements, ['fountain', 'fdx'], {
        title: 'My Script',
        author: 'Test Author',
        includeCoverPage: true,
      });
      for (const r of result.results) {
        expect(r.filename).toContain('My_Script');
      }
    });
  });

  describe('exportToRawText', () => {
    it('exports formatted raw text', () => {
      const text = manager.exportToRawText(sampleElements);
      expect(text).toContain('INT. COFFEE SHOP - DAY');
      expect(text).toContain('JESSICA');
    });

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

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

    it('preserves dialogue case', () => {
      const text = manager.exportToRawText(sampleElements);
      expect(text).toContain('Hello there.');
    });

    it('uses standard template by default', () => {
      const text = manager.exportToRawText(sampleElements);
      expect(text.length).toBeGreaterThan(0);
    });

    it('supports sitcom template', () => {
      const text = manager.exportToRawText(sampleElements, 'sitcom');
      expect(text.length).toBeGreaterThan(0);
    });
  });
});
