import type { ScreenplayElement, TemplateType } from '../screenplay/types';
import { getTemplate } from '../screenplay/format';

export interface PreviewOptions {
  template?: TemplateType;
  maxLines?: number;
  characterCount?: boolean;
  pageCount?: boolean;
}

export interface PreviewResult {
  text: string;
  stats: PreviewStats;
}

export interface PreviewStats {
  totalElements: number;
  totalPages: number;
  dialogueCount: number;
  actionCount: number;
  sceneCount: number;
  characterCount: number;
  parentheticalCount: number;
  transitionCount: number;
  estimatedPages: number;
}

const LINES_PER_PAGE = 55;

export function generatePreview(elements: ScreenplayElement[], options: PreviewOptions = {}): PreviewResult {
  const template = getTemplate(options.template || 'standard');
  const maxLines = options.maxLines ?? 200;

  const lines: string[] = [];

  if (options.pageCount) {
    const estimatedPages = estimatePageCount(elements);
    lines.push(`Estimated length: ${estimatedPages} pages`);
    lines.push('');
  }

  let lineCount = 0;
  for (const el of elements) {
    if (lineCount >= maxLines) {
      lines.push('... (truncated)');
      break;
    }

    const style = template.elementStyles[el.type];
    const contentLines = el.content.trim().split('\n');

    for (const line of contentLines) {
      if (lineCount >= maxLines) {
        lines.push('... (truncated)');
        break;
      }

      let formatted = line.trim();
      if (style.uppercase) formatted = formatted.toUpperCase();

      const indent = '  '.repeat(Math.round(style.indentStart * 2));
      lines.push(indent + formatted);
      lineCount++;
    }

    if (style.marginBottom > 0) {
      lines.push('');
      lineCount++;
    }
  }

  const stats = computeStats(elements);

  return {
    text: lines.join('\n'),
    stats,
  };
}

export function computeStats(elements: ScreenplayElement[]): PreviewStats {
  let dialogueCount = 0;
  let actionCount = 0;
  let sceneCount = 0;
  let characterCount = 0;
  let parentheticalCount = 0;
  let transitionCount = 0;
  let totalLines = 0;

  for (const el of elements) {
    const contentLines = el.content.trim().split('\n').filter(l => l.trim() !== '');
    totalLines += contentLines.length;

    switch (el.type) {
      case 'dialogue':
        dialogueCount += contentLines.length;
        break;
      case 'action':
        actionCount += contentLines.length;
        break;
      case 'sceneHeading':
        sceneCount++;
        totalLines += 1;
        break;
      case 'character':
        characterCount++;
        break;
      case 'parenthetical':
        parentheticalCount++;
        break;
      case 'transition':
        transitionCount++;
        break;
    }
  }

  const estimatedPages = Math.ceil(totalLines / LINES_PER_PAGE);

  return {
    totalElements: elements.length,
    totalPages: estimatedPages,
    dialogueCount,
    actionCount,
    sceneCount,
    characterCount,
    parentheticalCount,
    transitionCount,
    estimatedPages,
  };
}

function estimatePageCount(elements: ScreenplayElement[]): number {
  let totalLines = 0;

  for (const el of elements) {
    const contentLines = el.content.trim().split('\n').filter(l => l.trim() !== '');
    totalLines += contentLines.length;

    const style = getTemplate('standard').elementStyles[el.type];
    if (style.marginBottom > 0) {
      totalLines += Math.ceil(style.marginBottom);
    }

    if (el.type === 'sceneHeading') {
      totalLines += 1;
    }
  }

  return Math.ceil(totalLines / LINES_PER_PAGE);
}
