import { default as default_2 } from 'react';
import { Editor as Editor_2 } from '@tiptap/react';
import { Extension } from '@tiptap/core';
import { JSX } from 'react';
import { Mark } from '@tiptap/core';
import { Node as Node_2 } from '@tiptap/core';
import { NodeViewProps } from '@tiptap/react';
import { ReactNode } from 'react';

export declare const AxiomLike: Extension<any, any>;

export declare const Blocks: Extension<any, any>;

/**
 * The runtime safety guard.
 *
 * Answers: "if the user opens this document and immediately saves without
 * editing, is the file unchanged (apart from formatting)?" If not, some
 * construct in the document is outside the subset the editor can faithfully
 * represent, and enabling WYSIWYG editing would corrupt it.
 *
 * Never throws — every failure mode is folded into `{ safe: false }`:
 *  - malformed XML (cleanPtx's parser throws),
 *  - anything unexpected inside TipTap parsing,
 *  - a round-trip result that differs from `formatPretext(input)`.
 *
 * Cost note: this performs one cleanPtx pass, one ProseMirror parse, one
 * serialize, and two formatPretext runs. For typical section-sized files
 * this is a few milliseconds; callers should still avoid running it more
 * often than content actually changes (VisualEditor runs it only on
 * external content updates, which are already debounced upstream).
 */
export declare function checkRoundTrip(ptx: string): RoundTripReport;

export declare function cleanPtx(origXml: string): string;

declare interface CursorPosition {
    pos: () => number;
    depth: () => number;
    inTextNode: () => boolean;
    prevNodeIsText: () => boolean;
    nextNodeIsText: () => boolean;
    parentType: () => string;
    anchor: () => any;
    nextNodeSize: () => number;
    prevNodeSize: () => number;
}

export declare const Definition: Node_2<any, any>;

export declare const Divisions: Extension<any, any>;

declare interface Editor {
    $pos: (pos: number) => any;
    state: {
        selection: {
            $anchor: {
                pos: number;
                depth: number;
                parent: {
                    firstChild: {
                        isText: boolean;
                    } | null;
                    type: {
                        name: string;
                    };
                };
                nodeBefore: {
                    isText: boolean;
                    nodeSize: number;
                } | null;
                nodeAfter: {
                    type: {
                        name: string;
                    };
                    nodeSize: number;
                } | null;
            };
        };
    };
}

/**
 * The full, canonical extension list: base nodes/marks plus attribute
 * preservation. This is what the live editor, the guard, and the tests all
 * consume.
 */
export declare const editorExtensions: (Node_2<any, any> | Extension<any, any>)[];

/**
 * TipTap's JSON document shape. We keep this loose (rather than importing
 * TipTap's `JSONContent`) because `json2ptx` has its own structural type and
 * everything here just passes the JSON through opaquely.
 */
export declare type EditorJson = Record<string, unknown>;

/**
 * The set of source tags the editor schema can genuinely represent — every
 * node and mark, translated to its PreTeXt tag name (tt2ptx maps the
 * TipTap-native names: bulletList→ul etc.).
 *
 * This is what cleanPtx's "known tags" list MUST equal: a tag listed as
 * known but missing from the schema gets destroyed by the parser instead of
 * being safely rawptx-wrapped (that bug shipped four times: conclusion,
 * part, worksheet, pre). KNOWN_TAGS in knownTags.ts stays a static list so
 * utils.ts needn't import this module (which would be circular — the
 * extension files import utils.ts), and a test in roundtrip.spec.ts asserts
 * the two sets are identical, so any drift fails CI.
 */
export declare const editorSourceTags: ReadonlySet<string>;

export declare const Emph: Node_2<any, any>;

export declare const ExampleLike: Extension<any, any>;

export declare const getCursorPos: (editor: Editor) => CursorPosition;

export declare const Inline: Extension<any, any>;

/**
 * Serialize a TipTap/ProseMirror document (as JSON) back to PreTeXt XML.
 *
 * @param json       The editor document; its top node must be `ptxFragment`
 *                   (see editorExtensions.ts).
 * @param inlineTags Node type names to serialize inline (no injected
 *                   newlines). Defaults to DEFAULT_INLINE_TAGS; roundtrip.ts
 *                   passes the set derived from the actual editor schema.
 */
export declare function json2ptx(json: JsonNode, inlineTags?: ReadonlySet<string>): string;

declare interface JsonNode {
    type: string;
    content?: JsonNode[];
    /**
     * ProseMirror attributes. `ptxAttrs` is special: it is the catch-all
     * record of the node's original SOURCE attributes, captured by the
     * PtxSourceAttributes extension (editorExtensions.ts); attrString expands
     * it back into individual XML attributes. Any other key is an attribute
     * some TipTap extension declared directly (e.g. codeBlock's `language`).
     */
    attrs?: Record<string, unknown>;
    text?: string;
    /**
     * Marks attached to this node. Present on text nodes AND on inline
     * element nodes (a chip or <m> inside an <em> span carries the em mark).
     * ProseMirror stores marks in schema-rank order (see Inline.ts for the
     * rank ordering), which processChildren relies on for its run-merging.
     * Mark attributes are ignored — none of the PreTeXt marks we model
     * (em/term/alert/c) carry attributes.
     */
    marks?: Array<{
        type: string;
    }>;
}

export declare const KeyboardCommands: Extension<any, any>;

/**
 * The PreTeXt source tags the visual editor can represent.
 *
 * CONTRACT: this list must contain exactly the tags backed by the editor
 * schema (nodes + marks, translated to their PreTeXt tag names). cleanPtx
 * (utils.ts) passes tags on this list through to the TipTap parser and
 * wraps everything else in the rawptx escape hatch. A tag listed here
 * WITHOUT a schema node behind it is the worst kind of bug: cleanPtx skips
 * the safety wrapper and ProseMirror then silently destroys the element
 * (this shipped four times: conclusion, part, worksheet, pre).
 *
 * The authoritative set is derived from the real schema as
 * `editorSourceTags` in editorExtensions.ts; this static copy exists only
 * because utils.ts cannot import editorExtensions.ts (the extension files
 * import utils.ts — it would be a cycle). A test in roundtrip.spec.ts
 * asserts the two sets are identical, so any drift fails CI.
 *
 * When you add a new element extension: register it in editorExtensions.ts
 * AND add its tag here (the sync test will remind you), plus a green
 * fixture in roundtrip.spec.ts proving it round-trips.
 */
export declare const KNOWN_TAGS: string[];

export declare const MathDisplay: Node_2<any, any>;

export declare const MathEquation: Node_2<any, any>;

export declare const MathInline: Node_2<any, any>;

export declare const MenuBar: (props: MenuBarProps) => JSX.Element;

export declare interface MenuBarProps {
    isChecked: boolean;
    onChange: () => void;
    title?: string;
    onTitleChange?: (value: string) => void;
    onSaveButton?: () => void;
    saveButtonLabel?: string;
    onCancelButton?: () => void;
    cancelButtonLabel?: string;
    showPreviewModeToggle?: boolean;
    feedbackControl?: ReactNode;
}

/** Result of parsing a PreTeXt string into editor state. */
export declare interface ParsedPtx {
    /**
     * The XML declaration (`<?xml ... ?>`) from the top of the input, if any.
     * The editor cannot represent it (it is not an element), so we capture it
     * here and `serializeEditorJson` re-prepends it. Without this, every save
     * would strip the declaration — which the round-trip guard would then
     * (correctly) flag on every ordinary PreTeXt file.
     */
    xmlDecl: string | null;
    /**
     * The cleaned XML actually handed to the TipTap parser: declaration
     * stripped, wrapped in `<ptxdoc>`, unknown tags wrapped in `<rawptx>`.
     */
    cleanedXml: string;
    /** The TipTap/ProseMirror document JSON produced by parsing `cleanedXml`. */
    json: EditorJson;
}

/**
 * Parse a PreTeXt XML string into TipTap editor JSON.
 *
 * This is the exact parse the live editor performs (same `cleanPtx`
 * preprocessing, same extension list), factored out so the guard and the
 * tests can run it headlessly. VisualEditor.tsx also feeds the returned
 * `json` straight into `editor.commands.setContent`, which guarantees the
 * editor holds precisely the state the guard verified — no second parse
 * that could diverge.
 *
 * Throws if the input is not well-formed XML (`cleanPtx`'s parser throws);
 * `checkRoundTrip` catches that and reports it as an unsafe document.
 */
export declare function parsePtx(ptx: string): ParsedPtx;

export declare const ProofComponent: () => JSX.Element;

export declare const PtxBubbleMenu: ({ editor }: {
    editor: Editor_2;
}) => default_2.JSX.Element;

export declare const PtxFloatingMenu: ({ editor }: {
    editor: Editor_2;
}) => default_2.JSX.Element;

export declare const RawPtx: Node_2<any, any>;

export declare const RawPtxInline: Node_2<any, any>;

/**
 * Run a full editor round-trip on a PreTeXt string: parse it exactly as the
 * editor would, then serialize it exactly as a save would. No editing in
 * between — so for a lossless document the result equals
 * `formatPretext(input)`.
 *
 * Exposed primarily for the test harness; `checkRoundTrip` wraps it with
 * error handling and the comparison.
 */
export declare function roundTripPtx(ptx: string): string;

/** Verdict returned by {@link checkRoundTrip}. */
export declare interface RoundTripReport {
    /**
     * true  → the document survives parse+serialize unchanged (modulo
     *         formatting); editing can be enabled with confidence.
     * false → the round-trip alters the document (or the document could not
     *         be processed at all); the editor must stay read-only.
     */
    safe: boolean;
    /**
     * Human-readable explanation when `safe` is false. Shown to the user in
     * the VisualEditor warning banner.
     */
    reason?: string;
    /**
     * `formatPretext(input)` — what an untouched save *should* produce.
     * Present whenever the comparison ran (i.e. parsing succeeded).
     */
    expected?: string;
    /**
     * The actual round-trip output. Diffing `expected` vs `actual` pinpoints
     * exactly which construct was lost; the test harness prints both on
     * failure for the same reason.
     */
    actual?: string;
    /**
     * The parse result, when parsing succeeded — returned so the caller
     * (VisualEditor) can reuse it for `setContent` instead of parsing the
     * document a second time. This both saves work and guarantees the state
     * loaded into the editor is the state the guard verified.
     */
    parsed?: ParsedPtx;
}

/**
 * Serialize TipTap editor JSON back to formatted PreTeXt XML.
 *
 * This is the write-back path: `json2ptx` turns the ProseMirror document
 * into PreTeXt tags, `formatPretext` normalizes the result, and the XML
 * declaration captured at parse time (if any) is restored on top.
 *
 * VisualEditor.tsx calls this from `onUpdate`, and `roundTripPtx` calls it
 * to complete the parse→serialize loop, so what the guard checks is
 * byte-for-byte the same function the editor saves with.
 */
export declare function serializeEditorJson(json: EditorJson, xmlDecl?: string | null): string;

export declare const Statement: Node_2<any, any>;

export declare const TheoremLikeComponent: (props: NodeViewProps) => JSX.Element;

export declare const TheoremLikeExtension: Extension<any, any>;

export declare const Title: Node_2<any, any>;

export declare const UnknownMark: Mark<any, any>;

export declare const Url: Node_2<any, any>;

export declare const VisualEditor: ({ content, onChange, canEdit, editDisabledReason, }: VisualEditorProps) => JSX.Element;

declare interface VisualEditorProps {
    /** PreTeXt XML string to render and (optionally) edit. */
    content: string;
    /**
     * Called (debounced 500 ms) with updated PreTeXt XML whenever the user edits
     * content. Only fired when editing is enabled.
     */
    onChange: (html: string) => void;
    /**
     * Whether editing is allowed. Defaults to `true`.
     * When `false`, the editor stays read-only and the "Edit" toggle is hidden.
     */
    canEdit?: boolean;
    /**
     * Message shown when editing is disabled.
     */
    editDisabledReason?: string;
}

export { }
