/**
 * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
 */
/**
 * @module ai/aireviewcore/aireviewcoreediting
 */
import { InsertOperation, MarkerOperation, ModelDocumentFragment, ModelPosition, ModelRange, type Operation } from '@ckeditor/ckeditor5-engine';
import { type Emitter } from '@ckeditor/ckeditor5-utils';
import { ContextPlugin, Editor, type Context } from '@ckeditor/ckeditor5-core';
import { DocumentCompare } from '@ckeditor/ckeditor5-collaboration-core';
import { type AIReviewCheckResultChange } from './model/aireviewcheckresultchange.js';
import { AIEditing } from '../aicore/aiediting.js';
export declare class AIReviewCoreEditing extends ContextPlugin {
    /**
     * @inheritDoc
     */
    static get requires(): readonly [typeof DocumentCompare, typeof AIEditing];
    /**
     * @inheritDoc
     */
    static get pluginName(): "AIReviewCoreEditing";
    /**
     * @inheritDoc
     */
    static get isOfficialPlugin(): true;
    /**
     * @inheritDoc
     */
    static get isPremiumPlugin(): true;
    /**
     * @inheritDoc
     */
    constructor(context: Context | Editor);
    /**
     * Exposes the event emitter to allow listening to specific events.
     */
    get emitter(): Emitter;
    /**
     * @inheritDoc
     */
    afterInit(): void;
    /**
     * Returns the data (as string and flat list of container elements) and version of the current document.
     *
     * This method also applied `data-id` attributes to all elements that are direct parents of text nodes.
     * These attributes are used by AI API to determine that given element can be changed.
     *
     * Additionally, each element is converted from model to HTML string in the context of the entire structure
     * to ensure that the conversion is accurate (e.g. table cells need to be inside a table row, which needs to be inside a table).
     */
    getDocumentData(): AIDocumentData;
    /**
     * Compares two pieces of content, calculates operations, groups them and returns diffed content
     * and additional data for each group.
     *
     * Each group contains:
     * - `operations`: list of operations that are part of the group.
     * - `operationsIsolated`: list of operations that are part of the group but with positions/ranges re-calculated
     * to allow applying them in isolation (without other operations that would affect their positions).
     * - `groupOffset`: how many characters were inserted in this group.
     * - `content`: function that returns content (as HTML string) of the entire content with all changes applied and context marked.
     * - `context`: function that returns part of the content (as HTML string) consider as group context, with all changes applied
     * for this specific context.
     *
     * Operations processing logic is simplified assuming only `Insert` and `Marker` operations. Other operations, even if present
     * in the calculated operations, are ignored.
     *
     * There are two modes of processing diffed content that affects the output of this method. The modes
     * are controlled with `asSingleGroup` parameter.
     *
     * Default mode (`asSingleGroup` is `false`):
     *
     * By default each group of operations is processed separately. This mode is used by "AI Review Mode" feature code.
     *
     * The `context` is a range within a block that includes operations from a specific group, starts after the previous
     * change, and ends before the next change. If there is a single group, it spans over the entire block element contents.
     *
     * For example:
     * Initial content:  <p>Foo bar baz. 123 456 789.</p>
     * New content:      <p>Foo bax baz. 123 789.</p>
     *
     * This can be visualized as ('[]' shows removal, '{}' shows insertion):
     * <p>Foo[ bar]{ bax} baz. 123[ 456] 789.</p>
     *
     * There are 2 separate operation groups:
     * - " bar" -> " bax" (marker remove operation + insert operation)
     * - " 456" removed (marker remove operation)
     *
     * The context of each group (marked with '()') is:
     * Group 1: <p>(Foo[ bar]{ bax} baz. 123) 456 789.</p>
     * Group 2: <p>Foo bar( baz. 123 456 789.)</p>
     *
     * Single group mode (`asSingleGroup` is `true`):
     *
     * A single group mode assumes that entire content block are changed as a single change. This mode
     * is used by "AI Translate" feature code.
     *
     * Here, the contents are diffed the same, but then based on calculated operations, a single group with one
     * marker remove operation (spanning all removed content) and a single insert operation (spanning all inserted content)
     * is created.
     *
     * For example:
     * Initial content:  <p>Foo bar baz. 123 456 789.</p>
     * New content:      <p>Foo bax baz. 123 789.</p>
     *
     * This can be visualized as ('[]' shows removal, '{}' shows insertion):
     * <p>[Foo bar bax baz. 123 456 789.]{Foo bax baz. 123 789.}</p>
     *
     * The context and content is equal so both functions return the entire initial content.
     */
    diffContent(editor: Editor, contentInitial: string, contentNew: string, asSingleGroup?: boolean): Array<AIReviewCoreChangeData>;
    markChangePositionInEditorContent(changes: Array<AIReviewCheckResultChange>, documentData: AIDocumentData): void;
    clearAllMarkers(): void;
    switchToReadOnly(): void;
    switchToEdit(): void;
    applyChange(changeIds: Array<string>): void;
    rejectChange(changeId: string): void;
    getEditor(): Editor;
    /**
     * All editors attached to this context (same order as {@link module:ai/aicore/utils/geteditorfromcontext~getEditorsFromContext}).
     */
    getEditors(): Array<Editor>;
    /**
     * Returns the editor that hosts markers for the given change, when known.
     */
    getEditorForChange(changeId: string): Editor | undefined;
    getMarkerElementForChange(changeId: string): {
        modelRange: ModelRange;
        getElement: () => HTMLElement | null;
    } | null;
    /**
     * Returns the top-level DOM element that includes the change with the given id.
     */
    getContentElementForChange(changeId: string): HTMLElement | null;
    /**
     * A shortcut method to clear active markers and set others as active. It also
     * checks what was the previous state to avoid unnecessary operations, so it should
     * be used in scenarios when there is a chance that something will trigger the same markers
     * activation multiple times (e.g. hovering over complex content with multiple markers
     * from the same change).
     */
    reactivateMarkers(changeId: string): void;
    /**
     * Adds a 'ck-ai-review__change_active' class to all marker elements related to the given change ID,
     * within a limited range (usually top-level block element) in the editor content.
     * There can be multiple markers related to a single change (e.g. insertion and removal markers) split
     * into multiple spans in the view layer.
     */
    setMarkersInElementAsActive(changeId: string): void;
    /**
     * Removes 'ck-ai-review__change_active' class from all active marker elements in the editor content.
     */
    setAllMarkersAsInactive(): void;
}
export type AIDocumentDataElement = {
    /**
     * Editor instance this element's model belongs to.
     */
    editor: Editor;
    /**
     * Name of the model root this element belongs to (e.g. `main`, `root1` in multi-root editors).
     */
    rootName: string;
    /**
     * Path to the element in the model.
     */
    path: Array<number>;
    /**
     * Model document version when this element map was captured (per-editor).
     */
    documentVersion: number;
    getContent: () => string;
};
export type AIDocumentData = {
    /**
     * Single string passed to review API: roots serialized in model order, concatenated.
     */
    content: string;
    elements: Map<string, AIDocumentDataElement>;
};
export type AIDiffResult = {
    content: string;
    operations: Array<Operation>;
};
export type AIReviewCoreMarkerBaseData = {
    groupId: string;
    type: AIReviewCoreMarkerType;
    content?: {
        asString: string;
        asFragment: ModelDocumentFragment;
    };
};
export type AIReviewCoreMarkerInsertData = AIReviewCoreMarkerBaseData & {
    start: ModelPosition;
    end: ModelPosition;
};
export type AIReviewCoreMarkerData = AIReviewCoreMarkerBaseData & {
    id: string;
    editor: Editor;
};
export type AIReviewCoreMarkerType = 'insert' | 'remove-text' | 'remove-only' | 'remove-context';
export type AIReviewCoreChangeRange = {
    operations: Array<InsertOperation | MarkerOperation>;
    operationsIsolated: Array<InsertOperation | MarkerOperation>;
    groupOffset: number;
};
export type AIReviewCoreChangeData = AIReviewCoreChangeRange & {
    content: () => string;
    context: () => string;
};
export type AIReviewCoreChangeMarkerClickedEvent = {
    name: 'changeMarkerClicked';
    args: [
        {
            markerId: string;
            changeId: string;
            markerElement: () => HTMLElement | null;
            domEvent: MouseEvent;
        }
    ];
};
export type AIReviewCoreChangeMarkerRemovedEvent = {
    name: 'changeMarkerRemoved';
    args: [
        {
            markerId: string;
            changeId: string;
        }
    ];
};
export type AIReviewCoreChangeMarkerRestoredEvent = {
    name: 'changeMarkerRestored';
    args: [
        {
            markerId: string;
            changeId: string;
        }
    ];
};
export type AIReviewCoreChangeMarkerBlurredEvent = {
    name: 'changeMarkerBlurred';
    args: [];
};
export type AIReviewCoreChangeMarkerHoveredEvent = {
    name: 'changeMarkerHovered';
    args: [
        {
            changeId: string;
            markerElement: () => HTMLElement | null;
            domEvent: MouseEvent;
        }
    ];
};
