/**
 * StarterKit — bundles all extensions into a ready-to-use set
 *
 * Usage:
 *   const extensions = createStarterKit();
 *   const manager = new ExtensionManager(extensions);
 *   manager.buildSchema();
 *   manager.initializeRuntime();
 */

import type { AnyExtension } from './types';
import type { SelectionChangeCallback } from '../plugins/selectionTracker';

// Core
import { DocExtension } from './core/DocExtension';
import { TextExtension } from './core/TextExtension';
import { ParagraphExtension } from './core/ParagraphExtension';
import { HistoryExtension } from './core/HistoryExtension';

// Marks
import { BoldExtension } from './marks/BoldExtension';
import { ItalicExtension } from './marks/ItalicExtension';
import { UnderlineExtension } from './marks/UnderlineExtension';
import { StrikeExtension } from './marks/StrikeExtension';
import { TextColorExtension } from './marks/TextColorExtension';
import { HighlightExtension } from './marks/HighlightExtension';
import { FontSizeExtension } from './marks/FontSizeExtension';
import { FontFamilyExtension } from './marks/FontFamilyExtension';
import { SuperscriptExtension } from './marks/SuperscriptExtension';
import { SubscriptExtension } from './marks/SubscriptExtension';
import { HyperlinkExtension } from './marks/HyperlinkExtension';
import { AllCapsExtension } from './marks/AllCapsExtension';
import { SmallCapsExtension } from './marks/SmallCapsExtension';
import { FootnoteRefExtension } from './marks/FootnoteRefExtension';
import { CharacterSpacingExtension } from './marks/CharacterSpacingExtension';
import { CommentExtension } from './marks/CommentExtension';
import { InsertionExtension, DeletionExtension } from './marks/TrackedChangeExtensions';
import {
  EmbossExtension,
  ImprintExtension,
  TextShadowExtension,
  EmphasisMarkExtension,
  TextOutlineExtension,
} from './marks/TextEffectsExtensions';
import { HiddenExtension, RtlExtension, TextEffectExtension } from './marks/HiddenTextExtensions';
import { RunStyleExtension } from './marks/RunStyleExtension';

// Nodes
import { HardBreakExtension } from './nodes/HardBreakExtension';
import { TabExtension } from './nodes/TabExtension';
import { ImageExtension } from './nodes/ImageExtension';
import { TextBoxExtension } from './nodes/TextBoxExtension';
import { ShapeExtension } from './nodes/ShapeExtension';
import { HorizontalRuleExtension } from './nodes/HorizontalRuleExtension';
import { PageBreakExtension } from './nodes/PageBreakExtension';
import { FieldExtension } from './nodes/FieldExtension';
import { SdtExtension } from './nodes/SdtExtension';
import { BlockSdtExtension } from './nodes/BlockSdtExtension';
import { MathExtension } from './nodes/MathExtension';
import { createTableExtensions } from './nodes/TableExtension';

// Features
import { ListExtension } from './features/ListExtension';
import { BaseKeymapExtension } from './features/BaseKeymapExtension';
import { EmptyParagraphFormatExtension } from './features/EmptyParagraphFormatExtension';
import { SelectionTrackerExtension } from './features/SelectionTrackerExtension';
import { ImageDragExtension } from './features/ImageDragExtension';
import { ImagePasteExtension } from './features/ImagePasteExtension';
import { DropCursorExtension } from './features/DropCursorExtension';
import { ParagraphChangeTrackerExtension } from './features/ParagraphChangeTrackerExtension';
import { ParaIdAllocatorExtension } from './features/ParaIdAllocatorExtension';
import { BidiShortcutExtension } from './features/BidiShortcutExtension';
import { PasteStyleInlinerExtension } from './features/PasteStyleInlinerExtension';

export interface StarterKitOptions {
  /** Extensions to disable by name */
  disable?: string[];
  /** History depth (default: 100) */
  historyDepth?: number;
  /** History new group delay (default: 500) */
  historyNewGroupDelay?: number;
  /** Selection change callback */
  onSelectionChange?: SelectionChangeCallback;
}

/**
 * Create the full set of extensions for the DOCX editor
 */
export function createStarterKit(options: StarterKitOptions = {}): AnyExtension[] {
  const disabled = new Set(options.disable || []);

  const extensions: AnyExtension[] = [];

  function add(name: string, ext: AnyExtension): void {
    if (!disabled.has(name)) {
      extensions.push(ext);
    }
  }

  // Core (always included unless explicitly disabled)
  add('doc', DocExtension());
  add('text', TextExtension());
  add('paragraph', ParagraphExtension());
  add(
    'history',
    HistoryExtension({
      depth: options.historyDepth,
      newGroupDelay: options.historyNewGroupDelay,
    })
  );

  // Marks
  add('bold', BoldExtension());
  add('italic', ItalicExtension());
  add('underline', UnderlineExtension());
  add('strike', StrikeExtension());
  add('textColor', TextColorExtension());
  add('highlight', HighlightExtension());
  add('fontSize', FontSizeExtension());
  add('fontFamily', FontFamilyExtension());
  add('superscript', SuperscriptExtension());
  add('subscript', SubscriptExtension());
  add('hyperlink', HyperlinkExtension());
  add('allCaps', AllCapsExtension());
  add('smallCaps', SmallCapsExtension());
  add('footnoteRef', FootnoteRefExtension());
  add('characterSpacing', CharacterSpacingExtension());
  add('emboss', EmbossExtension());
  add('imprint', ImprintExtension());
  add('textShadow', TextShadowExtension());
  add('emphasisMark', EmphasisMarkExtension());
  add('textOutline', TextOutlineExtension());
  add('hidden', HiddenExtension());
  add('rtl', RtlExtension());
  add('runStyle', RunStyleExtension());
  add('textEffect', TextEffectExtension());
  add('comment', CommentExtension());
  add('insertion', InsertionExtension());
  add('deletion', DeletionExtension());

  // Nodes
  add('hardBreak', HardBreakExtension());
  add('tab', TabExtension());
  add('image', ImageExtension());
  add('textBox', TextBoxExtension());
  add('shape', ShapeExtension());
  add('imageDrag', ImageDragExtension());
  add('imagePaste', ImagePasteExtension());
  add('dropCursor', DropCursorExtension());
  add('horizontalRule', HorizontalRuleExtension());
  add('pageBreak', PageBreakExtension());
  add('field', FieldExtension());
  add('sdt', SdtExtension());
  add('blockSdt', BlockSdtExtension());
  add('math', MathExtension());

  // Table (5 extensions grouped)
  if (!disabled.has('table')) {
    extensions.push(...createTableExtensions());
  }

  // Features
  add('pasteStyleInliner', PasteStyleInlinerExtension());
  add('list', ListExtension());
  add('baseKeymap', BaseKeymapExtension());
  add('emptyParagraphFormat', EmptyParagraphFormatExtension());
  add(
    'selectionTracker',
    SelectionTrackerExtension({
      onSelectionChange: options.onSelectionChange,
    })
  );
  add('paragraphChangeTracker', ParagraphChangeTrackerExtension());
  // Run after the change tracker so it sees paragraphs in their final
  // state. Allocates `paraId` for any paragraph without one (e.g. new
  // paragraphs from Enter / paste / programmatic insertion).
  add('paraIdAllocator', ParaIdAllocatorExtension());
  add('bidiShortcut', BidiShortcutExtension());

  return extensions;
}
