/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow strict
 */

import type {
  EditorConfig,
  LexicalNode,
  NodeKey,
  ParagraphNode,
  RangeSelection,
  EditorThemeClasses,
  LexicalEditor,
} from 'lexical';

import {ElementNode, TextNode} from 'lexical';

declare export class CodeNode extends ElementNode {
  static getType(): string;
  static clone(node: CodeNode): CodeNode;
  constructor(language: ?string, key?: NodeKey): void;
  createDOM(config: EditorConfig): HTMLElement;
  updateDOM(prevNode: CodeNode, dom: HTMLElement): boolean;
  insertNewAfter(
    selection: RangeSelection,
    restoreSelection?: boolean,
  ): null | ParagraphNode | CodeHighlightNode;
  canInsertTab(): boolean;
  collapseAtStart(): true;
  setLanguage(language: string): void;
  getLanguage(): string | void;
}
declare export function $createCodeNode(language: ?string): CodeNode;
declare export function $isCodeNode(
  node: ?LexicalNode,
): boolean %checks(node instanceof CodeNode);

declare export function getFirstCodeHighlightNodeOfLine(
  anchor: LexicalNode,
): ?CodeHighlightNode;

declare export function getLastCodeHighlightNodeOfLine(
  anchor: LexicalNode,
): ?CodeHighlightNode;

declare export function getDefaultCodeLanguage(): string;
declare export function getCodeLanguages(): Array<string>;

declare export class CodeHighlightNode extends TextNode {
  __highlightType: ?string;
  constructor(text: string, highlightType?: string, key?: NodeKey): void;
  static getType(): string;
  // $FlowFixMe
  static clone(node: CodeHighlightNode): CodeHighlightNode;
  createDOM(config: EditorConfig): HTMLElement;
  updateDOM(
    // $FlowFixMe
    prevNode: CodeHighlightNode,
    dom: HTMLElement,
    config: EditorConfig,
  ): boolean;
  setFormat(format: number): this;
}

type TokenContent = string | Token | (string | Token)[];
export interface Token {
  type: string;
  content: TokenContent;
}
export interface Tokenizer {
  defaultLanguage: string;
  tokenize(code: string, language?: string): (string | Token)[];
}

declare function getHighlightThemeClass(
  theme: EditorThemeClasses,
  highlightType: ?string,
): ?string;
declare export function $createCodeHighlightNode(
  text: string,
  highlightType?: string,
): CodeHighlightNode;
declare export function $isCodeHighlightNode(
  node: ?LexicalNode,
): boolean %checks(node instanceof CodeHighlightNode);

declare export function registerCodeHighlighting(
  editor: LexicalEditor,
  tokenizer?: Tokenizer,
): () => void;
