import { describe, it, expect } from 'vitest';
import { FdxExporter } from './fdx';
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: 'parenthetical', content: 'smiling' },
  { id: 'e6', type: 'transition', content: 'SMASH CUT TO:' },
  { id: 'e7', type: 'note', content: 'Writer note' },
  { id: 'e8', type: 'retained', content: 'Retained from v1' },
  { id: 'e9', type: 'centered', content: 'FADE OUT.' },
];

describe('FdxExporter', () => {
  const exporter = new FdxExporter();

  it('supports fdx format', () => {
    expect(exporter.supportedFormats).toContain('fdx');
  });

  it('produces valid XML structure', () => {
    const result = exporter.export(sampleElements, { format: 'fdx' });
    expect(result.data).toContain('<?xml version="1.0" encoding="UTF-8"?>');
    expect(result.data).toContain('<FDX version="8.0">');
    expect(result.data).toContain('</FDX>');
  });

  it('includes title page', () => {
    const result = exporter.export(sampleElements, {
      format: 'fdx',
      title: 'Test Script',
      author: 'Jane Doe',
    });
    expect(result.data).toContain('<TitlePage>');
    expect(result.data).toContain('<Title>Test Script</Title>');
    expect(result.data).toContain('<Author>Jane Doe</Author>');
  });

  it('includes font face and page setup', () => {
    const result = exporter.export(sampleElements, { format: 'fdx' });
    expect(result.data).toContain('FontFace');
    expect(result.data).toContain('PageSetup');
  });

  it('exports scene headings as SceneHeading tags', () => {
    const result = exporter.export(sampleElements, { format: 'fdx' });
    expect(result.data).toContain('<SceneHeading fontFaceId="0">INT. COFFEE SHOP - DAY</SceneHeading>');
  });

  it('exports action as Action tags', () => {
    const result = exporter.export(sampleElements, { format: 'fdx' });
    expect(result.data).toContain('<Action fontFaceId="0">A bustling coffee shop.</Action>');
  });

  it('exports characters in uppercase', () => {
    const result = exporter.export(sampleElements, { format: 'fdx' });
    expect(result.data).toContain('<Character fontFaceId="0">JESSICA</Character>');
  });

  it('exports dialogue', () => {
    const result = exporter.export(sampleElements, { format: 'fdx' });
    expect(result.data).toContain('<Dialogue fontFaceId="0">Hello there.</Dialogue>');
  });

  it('exports parentheticals', () => {
    const result = exporter.export(sampleElements, { format: 'fdx' });
    expect(result.data).toContain('<Parenthetical fontFaceId="0">smiling</Parenthetical>');
  });

  it('exports transitions in uppercase', () => {
    const result = exporter.export(sampleElements, { format: 'fdx' });
    expect(result.data).toContain('<Transition fontFaceId="0">SMASH CUT TO:</Transition>');
  });

  it('exports notes', () => {
    const result = exporter.export(sampleElements, { format: 'fdx' });
    expect(result.data).toContain('<Note fontFaceId="0">Writer note</Note>');
  });

  it('exports retained text', () => {
    const result = exporter.export(sampleElements, { format: 'fdx' });
    expect(result.data).toContain('<Retained fontFaceId="0">Retained from v1</Retained>');
  });

  it('exports centered text', () => {
    const result = exporter.export(sampleElements, { format: 'fdx' });
    expect(result.data).toContain('<Centered fontFaceId="0">FADE OUT.</Centered>');
  });

  it('escapes XML special characters', () => {
    const elements: ScreenplayElement[] = [
      { id: 'e1', type: 'action', content: 'A sign reads: "Hello & Goodbye"' },
    ];
    const result = exporter.export(elements, { format: 'fdx' });
    expect(result.data).toContain('&amp;');
    expect(result.data).toContain('&quot;');
  });

  it('uses correct content type and extension', () => {
    const result = exporter.export(sampleElements, { format: 'fdx' });
    expect(result.contentType).toBe('application/xml');
    expect(result.extension).toBe('.fdx');
  });

  it('generates filename from title', () => {
    const result = exporter.export(sampleElements, { format: 'fdx', title: 'My Script' });
    expect(result.filename).toBe('My_Script.fdx');
  });

  it('handles empty elements array', () => {
    const result = exporter.export([], { format: 'fdx' });
    expect(result.data).toContain('<Content>');
    expect(result.data).toContain('</Content>');
  });

  it('includes contact when provided', () => {
    const result = exporter.export(sampleElements, {
      format: 'fdx',
      contact: 'jane@example.com',
    });
    expect(result.data).toContain('<Contact>jane@example.com</Contact>');
  });
});
