import type { ScreenplayElement } from '../screenplay/types';
import type { ScreenplayExporter, ExportOptions, ExportResult } from './types';
import { CONTENT_TYPES, EXTENSIONS } from './types';

export class FountainExporter implements ScreenplayExporter {
  public readonly supportedFormats: readonly ['fountain'] = ['fountain'];

  public export(elements: ScreenplayElement[], options: ExportOptions): ExportResult {
    const lines: string[] = [];

    if (options.includeCoverPage) {
      lines.push(options.title || 'Untitled');
      lines.push('');
      if (options.author) lines.push('By ' + options.author);
      if (options.contact) lines.push(options.contact);
      if (options.datetime) lines.push(options.datetime);
      lines.push('');
      lines.push('***');
      lines.push('');
    }

    for (let idx = 0; idx < elements.length; idx++) {
      const el = elements[idx];
      if (!el) continue;
      const nextEl = elements[idx + 1];

      switch (el.type) {
        case 'sceneHeading':
          lines.push('# ' + el.content.trim().toUpperCase());
          lines.push('');
          break;

        case 'action':
          lines.push('  ' + el.content.trim());
          lines.push('');
          break;

        case 'character': {
          const charName = el.content.trim().toUpperCase();
          lines.push('= ' + charName + ' =');
          lines.push('');
          break;
        }

        case 'dialogue':
          lines.push(el.content.trim());
          lines.push('');
          break;

        case 'parenthetical':
          lines.push('(' + el.content.trim() + ')');
          lines.push('');
          break;

        case 'transition':
          lines.push('-> ' + el.content.trim().toUpperCase());
          lines.push('');
          break;

        case 'note':
          lines.push('> ' + el.content.trim());
          lines.push('');
          break;

        case 'centered':
          lines.push('  ' + el.content.trim());
          lines.push('');
          break;

        case 'retained':
          lines.push('  ' + el.content.trim());
          lines.push('');
          break;
      }

      void nextEl;
    }

    const content = lines.join('\n').trim();
    const filename = (options.title || 'screenplay').replace(/[^a-zA-Z0-9]/g, '_');

    return {
      format: 'fountain',
      contentType: CONTENT_TYPES.fountain,
      extension: EXTENSIONS.fountain,
      data: content,
      filename: filename + EXTENSIONS.fountain,
    };
  }
}
