/**
 * Auto-formatting engine for screenplay elements
 * Final Draft compatible formatting with template support
 */

import {
  TemplateConfig,
  ScreenplayElementType,
  ElementStyle,
  ScreenplayElement,
  FormatResult,
  TemplateType,
} from './types';

let idCounter = 0;
export function generateId(): string {
  return `el-${Date.now()}-${++idCounter}`;
}

const STANDARD_TEMPLATE: TemplateConfig = {
  name: 'standard',
  label: 'Standard Screenplay',
  pageWidth: 8.5,
  pageHeight: 11,
  topMargin: 1.0,
  bottomMargin: 1.0,
  leftMargin: 1.0,
  rightMargin: 1.0,
  fontSize: 12,
  fontFamily: '"Courier New", Courier, monospace',
  elementStyles: {
    sceneHeading: {
      textAlign: 'left',
      uppercase: true,
      bold: true,
      indentStart: 0,
      indentEnd: 0,
      lineHeight: 2,
      marginBottom: 1,
    },
    action: {
      textAlign: 'left',
      uppercase: false,
      bold: false,
      indentStart: 0,
      indentEnd: 0,
      lineHeight: 1,
      marginBottom: 1,
    },
    character: {
      textAlign: 'left',
      uppercase: true,
      bold: false,
      indentStart: 3.7,
      indentEnd: 0,
      lineHeight: 1,
      marginBottom: 0,
    },
    dialogue: {
      textAlign: 'left',
      uppercase: false,
      bold: false,
      indentStart: 2.5,
      indentEnd: 2.5,
      lineHeight: 1,
      marginBottom: 0,
    },
    parenthetical: {
      textAlign: 'left',
      uppercase: false,
      bold: false,
      indentStart: 3.1,
      indentEnd: 3.5,
      lineHeight: 1,
      marginBottom: 0,
    },
    transition: {
      textAlign: 'right',
      uppercase: true,
      bold: false,
      indentStart: 0,
      indentEnd: 1.5,
      lineHeight: 1,
      marginBottom: 1,
    },
    note: {
      textAlign: 'left',
      uppercase: false,
      bold: false,
      indentStart: 1.0,
      indentEnd: 1.0,
      lineHeight: 1,
      marginBottom: 0.5,
    },
    retained: {
      textAlign: 'left',
      uppercase: false,
      bold: true,
      indentStart: 0,
      indentEnd: 0,
      lineHeight: 1,
      marginBottom: 0,
    },
    centered: {
      textAlign: 'center',
      uppercase: false,
      bold: false,
      indentStart: 0,
      indentEnd: 0,
      lineHeight: 1,
      marginBottom: 1,
    },
  },
};

const SITCOM_TEMPLATE: TemplateConfig = {
  name: 'sitcom',
  label: 'Sitcom / Multi-Camera',
  pageWidth: 8.5,
  pageHeight: 11,
  topMargin: 1.0,
  bottomMargin: 1.0,
  leftMargin: 1.0,
  rightMargin: 1.0,
  fontSize: 12,
  fontFamily: '"Courier New", Courier, monospace',
  elementStyles: {
    sceneHeading: {
      textAlign: 'left',
      uppercase: true,
      bold: true,
      indentStart: 0,
      indentEnd: 0,
      lineHeight: 2,
      marginBottom: 1,
    },
    action: {
      textAlign: 'left',
      uppercase: false,
      bold: false,
      indentStart: 0,
      indentEnd: 0,
      lineHeight: 1,
      marginBottom: 1,
    },
    character: {
      textAlign: 'left',
      uppercase: true,
      bold: false,
      indentStart: 2.0,
      indentEnd: 0,
      lineHeight: 1,
      marginBottom: 0,
    },
    dialogue: {
      textAlign: 'left',
      uppercase: false,
      bold: false,
      indentStart: 2.5,
      indentEnd: 2.5,
      lineHeight: 1,
      marginBottom: 0,
    },
    parenthetical: {
      textAlign: 'left',
      uppercase: false,
      bold: false,
      indentStart: 3.1,
      indentEnd: 3.5,
      lineHeight: 1,
      marginBottom: 0,
    },
    transition: {
      textAlign: 'right',
      uppercase: true,
      bold: false,
      indentStart: 0,
      indentEnd: 1.5,
      lineHeight: 1,
      marginBottom: 1,
    },
    note: {
      textAlign: 'left',
      uppercase: false,
      bold: false,
      indentStart: 1.0,
      indentEnd: 1.0,
      lineHeight: 1,
      marginBottom: 0.5,
    },
    retained: {
      textAlign: 'left',
      uppercase: false,
      bold: true,
      indentStart: 0,
      indentEnd: 0,
      lineHeight: 1,
      marginBottom: 0,
    },
    centered: {
      textAlign: 'center',
      uppercase: false,
      bold: false,
      indentStart: 0,
      indentEnd: 0,
      lineHeight: 1,
      marginBottom: 1,
    },
  },
};

const PODCAST_TEMPLATE: TemplateConfig = {
  name: 'podcast',
  label: 'Podcast Script',
  pageWidth: 8.5,
  pageHeight: 11,
  topMargin: 1.0,
  bottomMargin: 1.0,
  leftMargin: 1.0,
  rightMargin: 1.0,
  fontSize: 12,
  fontFamily: '"Courier New", Courier, monospace',
  elementStyles: {
    sceneHeading: {
      textAlign: 'left',
      uppercase: true,
      bold: true,
      indentStart: 0,
      indentEnd: 0,
      lineHeight: 2,
      marginBottom: 1,
    },
    action: {
      textAlign: 'left',
      uppercase: false,
      bold: false,
      indentStart: 0,
      indentEnd: 0,
      lineHeight: 1,
      marginBottom: 1,
    },
    character: {
      textAlign: 'left',
      uppercase: true,
      bold: true,
      indentStart: 1.5,
      indentEnd: 0,
      lineHeight: 1,
      marginBottom: 0,
    },
    dialogue: {
      textAlign: 'left',
      uppercase: false,
      bold: false,
      indentStart: 2.0,
      indentEnd: 2.0,
      lineHeight: 1,
      marginBottom: 0.5,
    },
    parenthetical: {
      textAlign: 'left',
      uppercase: false,
      bold: false,
      indentStart: 2.5,
      indentEnd: 3.0,
      lineHeight: 1,
      marginBottom: 0,
    },
    transition: {
      textAlign: 'right',
      uppercase: true,
      bold: false,
      indentStart: 0,
      indentEnd: 1.5,
      lineHeight: 1,
      marginBottom: 1,
    },
    note: {
      textAlign: 'left',
      uppercase: false,
      bold: false,
      indentStart: 1.0,
      indentEnd: 1.0,
      lineHeight: 1,
      marginBottom: 0.5,
    },
    retained: {
      textAlign: 'left',
      uppercase: false,
      bold: true,
      indentStart: 0,
      indentEnd: 0,
      lineHeight: 1,
      marginBottom: 0,
    },
    centered: {
      textAlign: 'center',
      uppercase: false,
      bold: false,
      indentStart: 0,
      indentEnd: 0,
      lineHeight: 1,
      marginBottom: 1,
    },
  },
};

const TEMPLATES: Record<TemplateType, TemplateConfig> = {
  standard: STANDARD_TEMPLATE,
  sitcom: SITCOM_TEMPLATE,
  podcast: PODCAST_TEMPLATE,
};

export function getTemplate(name: TemplateType): TemplateConfig {
  return TEMPLATES[name];
}

export function getAllTemplates(): TemplateConfig[] {
  return Object.values(TEMPLATES);
}

export function elementTypeClass(type: ScreenplayElementType): string {
  return `screenplay-${type}`;
}

export function formatScreenplay(
  rawText: string,
  templateType: TemplateType = 'standard',
  detectElementType: (line: string) => ScreenplayElementType
): FormatResult {
  const lines = rawText.split('\n');
  const elements: ScreenplayElement[] = [];
  let currentType: ScreenplayElementType = 'action';
  let currentContent = '';

  const flushElement = () => {
    if (currentContent.trim()) {
      elements.push({
        id: generateId(),
        type: currentType,
        content: currentContent.trimEnd(),
      });
    }
    currentContent = '';
  };

  for (const line of lines) {
    const detected = detectElementType(line);

    if (detected !== currentType) {
      flushElement();
      currentType = detected;
    }

    currentContent += line + '\n';
  }

  flushElement();

  return { elements, template: templateType };
}

export function getStyleForElement(
  type: ScreenplayElementType,
  template: TemplateType
): ElementStyle {
  return getTemplate(template).elementStyles[type];
}

export function formatLineForPreview(
  content: string,
  type: ScreenplayElementType,
  template: TemplateType
): string {
  const style = getStyleForElement(type, template);
  let formatted = content;

  if (style.uppercase) {
    formatted = formatted.toUpperCase();
  }

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

  return formatted;
}
