import { NodeAlignmentMenu as AlignmentImage } from '@layers-app/editor-core';
import { AlignmentMenu } from '@layers-app/editor-core';
import { CLEAR_EDITOR_COMMAND } from 'lexical';
import { deleteNode } from '@layers-app/editor-core';
import { DOMExportOutput } from 'lexical';
import { Dropzone } from '@mantine/dropzone';
import { EditorConfig } from 'lexical';
import { LexicalEditor as EditorType } from 'lexical';
import { ElementNode } from 'lexical';
import { FC } from 'react';
import { FOCUS_COMMAND } from 'lexical';
import { IconProps } from '../../../@tabler/icons-react/dist/esm/icons/index.mjs';
import { JSX as JSX_2 } from 'react/jsx-runtime';
import { LexicalCommand } from 'lexical';
import { LexicalNode } from 'lexical';
import { MarkNode } from '@lexical/mark';
import { MouseEventHandler } from 'react';
import { NodeKey } from 'lexical';
import { ParagraphNode } from 'lexical';
import { PluginConfig } from '@layers-app/editor-core';
import { RangeSelection } from 'lexical';
import { ResizableContainer } from '@layers-app/editor-core';
import { RootNode } from 'lexical';
import { SerializedEditorState } from 'lexical';
import { SerializedElementNode } from 'lexical';
import { SerializedLexicalNode } from 'lexical';
import { SlashMenuConfig } from '@layers-app/editor-core';
import { Spread } from 'lexical';
import { UploadData } from '@layers-app/editor-core';

export declare const $createNewParagraph: (editor: EditorType) => void;

export declare type ActiveUserProfile<DATA extends object> = EditorUser<DATA> & {
    id: string;
};

export { AlignmentImage }

export { AlignmentMenu }

export { CLEAR_EDITOR_COMMAND }

declare interface CommentActions {
    add(params: {
        text: string;
        files: CommentAttachment[];
    }, quote: string): Promise<string | void>;
    delete(id: string): void;
    restore(id: string): void;
}

declare interface CommentAttachment {
    id: string;
    name: string;
    type: string;
    size: number;
    url: string;
    src: string;
    isImage: boolean;
    isTemp: boolean;
    raw?: File;
}

declare interface CommentController {
    activeCommentId: {
        ids: string[];
        source: 'editor' | 'panel' | null;
    };
    onHighlight?: (ids: string[] | null, source: 'editor' | 'panel') => void;
    actions: CommentActions;
    editorComments: Map<string, {
        id: string;
        deleted: boolean;
        resolution: CommentResolve;
    }>;
}

declare type CommentResolve = 'ACCEPTED' | 'REJECTED' | null | 'NONE';

export declare const CREATE_TEMPLATE: LexicalCommand<unknown>;

export declare const createMediaComponent: (imageNode: LexicalNode, replaceEmptyBlock?: boolean) => boolean;

export { deleteNode }

export { Dropzone }

export declare const Editor: <USER_DATA extends object, CHILD_PAGE extends PageData>({ initialContent, onChange, outputFormat, mode, maxHeight, onBlur, onFocus, fetchUploadMedia, fileChunkUploadApi, isOfficePreviewAvailable, onPreviewOffice, fetchPromptResult, fetchSmartPastePrompt, fetchSmartPasteStreamPrompt, fetchDeleteMedia, fetchRestoreMedia, pageId, commentController, maxFileSize, contentModalUploadImage, maxImageSizeError, debounce: debounceMs, disable, ws, excludeNodes, imagePickerSettings, childPages, linkablePages, language, shiftEnterInsertNewLine, editorRef, placeholder, plugins, onTrack, onCopySuccess, onCopyError, mentionSearch, onMentionsChange, getMentionUserInfo, }: EditorProps<USER_DATA, CHILD_PAGE>) => JSX_2.Element;

declare interface EditorProps<USER_DATA extends object = object, PAGE_DATA extends PageData = PageData> {
    initialContent: Root | string;
    outputFormat: outputFormat;
    onChange: (e: Root | string, text?: string) => void;
    onBlur?: (e: Root | string) => void;
    onFocus?: () => void;
    mode?: Mode;
    maxHeight?: number;
    fetchUploadMedia?: fetchUploadMedia;
    fileChunkUploadApi?: FileChunkUploadApi;
    isOfficePreviewAvailable?: boolean;
    onPreviewOffice?: OnPreviewOffice;
    fetchPromptResult?: fetchPromptResult;
    fetchSmartPastePrompt?: fetchPromptResult;
    fetchSmartPasteStreamPrompt?: fetchPromptStreamResult;
    fetchDeleteMedia?: fetchDeleteRestoreMedia;
    fetchRestoreMedia?: fetchDeleteRestoreMedia;
    maxFileSize?: number;
    pageId?: string;
    contentModalUploadImage?: React.FunctionComponent;
    maxImageSizeError?: () => void;
    commentController?: CommentController;
    debounce?: number;
    disable?: boolean;
    shiftEnterInsertNewLine?: boolean;
    ws?: EditorWebSocketProps<USER_DATA>;
    excludeNodes?: ExcludeNodes;
    imagePickerSettings?: ImagePickerSettings;
    childPages?: {
        items: PAGE_DATA[];
        isLoading: boolean;
    };
    linkablePages?: Pages[];
    language?: 'ru' | 'en' | 'es';
    editorRef?: {
        current: EditorType | null;
    };
    placeholder?: string;
    plugins?: PluginConfig[];
    onTrack?: EditorTrackFn;
    onCopySuccess?: (message: string) => void;
    onCopyError?: (message: string) => void;
    mentionSearch?: MentionSearchFn;
    onMentionsChange?: (mentions: MentionRef[]) => void;
    getMentionUserInfo?: MentionUserInfoFn;
}

declare type EditorTrackFn = (event: string, params?: Record<string, unknown>) => void;

export { EditorType }

declare type EditorUser<DATA extends object> = {
    color: string;
    name: string;
    awarenessData?: DATA;
};

declare interface EditorWebSocketProps<USER_DATA extends object> {
    url: string;
    id: string;
    user: EditorUser<USER_DATA>;
    getActiveUsers?: (users: ActiveUserProfile<USER_DATA>[]) => void;
}

export declare type ErrorDeleteImage = (error?: Error) => void;

export declare type ErrorUploadImage = (error?: Error) => void;

declare type ExcludeNodes = {
    [K in ExcludeNodesKey]?: boolean;
};

declare type ExcludeNodesKey = 'paragraph' | 'quote' | 'code' | 'table' | 'grid' | 'horizontal-rule' | 'caret-right' | 'emoji' | 'excalidraw' | 'childDocs' | 'photo' | 'video' | 'audio' | 'file' | 'embed' | 'form' | 'contents' | 'template' | 'componentPicker' | 'hashtag' | 'list' | 'check' | 'link' | 'comment' | 'swagger' | 'callout' | 'layout' | 'draggableBlock' | 'newParagraph' | 'actionMenu' | 'emptyPage' | '1' | '2' | '3' | 'number' | 'bullet' | 'default' | 'alert' | 'success' | 'warning' | 'images' | 'collapsible' | 'checkList' | 'horizontalRule' | 'inlinePageLink' | 'equation' | 'equation-inline' | 'pageLink' | 'codeHighlight' | 'smartPaste' | 'fastBackspace' | 'tabs';

export declare class ExtendMarkNode extends MarkNode implements ElementNode {
    __resolve: CommentResolve;
    constructor(idsExtend: string[], resolve?: CommentResolve, key?: NodeKey);
    static getType(): string;
    static clone(node: ExtendMarkNode): ExtendMarkNode;
    static importJSON(serializedNode: SerializedMarkNode): ExtendMarkNode;
    static importDOM(): null;
    resolveThreat(value: CommentResolve): void;
    createDOM(config: EditorConfig): HTMLElement;
    exportDOM(editor: EditorType): DOMExportOutput;
    updateDOM(prevNode: this, element: HTMLElement, config: EditorConfig): boolean;
    exportJSON(): SerializedMarkNode;
    excludeFromCopy(_destination: 'clone' | 'html'): boolean;
    updateExtendId(tempId: string, realId: string): void;
}

declare type fetchDeleteRestoreMedia = (id: string, success: SuccessDeleteImage, error?: ErrorDeleteImage) => void;

declare type fetchPromptResult = (prompt: string, success: (data: string) => void, error?: () => void) => void;

declare type fetchPromptStreamResult = (prompt: string, onBlock: (block: string) => void, onDone: () => void, onError?: () => void) => void;

declare type fetchUploadMedia = (file: File, success: SuccessUploadImage, error?: ErrorDeleteImage, signal?: AbortSignal, onProgress?: (percent: number) => void) => void;

declare interface FileChunkUploadApi {
    initAttachment: (file: File) => Promise<{
        attachmentId: string;
        url?: string;
        status?: {
            nextOffset?: number;
            uploadedBytes?: number;
        };
    }>;
    fetchContentStatus: (attachmentId: string) => Promise<{
        nextOffset?: number;
        uploadedBytes?: number;
    }>;
    uploadChunkWithProgress: (attachmentId: string, file: File, offset: number, end: number, total: number, signal?: AbortSignal, onProgress?: (loaded: number) => void, onXhrReady?: (xhr: XMLHttpRequest) => void) => Promise<{
        nextOffset?: number;
        expectedOffset?: number;
    }>;
}

export { FOCUS_COMMAND }

export declare function focusEditor(editor: EditorType, atStart?: boolean): void;

export declare const Icon: ({ name, iconStyle, ...rest }: {
    name: keyof typeof iconsBlockTypeToBlockName;
    [key: string]: any;
}) => JSX_2.Element;

declare const iconsBlockTypeToBlockName: Record<string, FC<IconProps>>;

declare type ImagePickerGalleryCollection = {
    id: string;
    path: string;
    url: string;
    title: string;
    items: string[];
};

declare type ImagePickerSettings = {
    maxUploadFiles?: number;
    unsplashClientId?: string;
    giphyToken?: string;
    download?: boolean;
    link?: boolean;
    galleryCollection?: ImagePickerGalleryCollection[];
};

export declare type MentionRef = {
    userId: string;
    name: string;
    anchorId?: string;
    preview?: string;
};

export declare type MentionSearchFn = (trigger: string, query: string) => Promise<MentionUser[]>;

export declare type MentionUser = {
    value: string;
    id: string;
    avatarUrl?: string;
};

export declare type MentionUserInfoFn = (userId: string) => MentionUserPreview | Promise<MentionUserPreview | null> | null;

export declare type MentionUserPreview = {
    id: string;
    name: string;
    avatarUrl?: string;
    roleLabel?: string;
    isYou?: boolean;
};

declare type Mode = 'comment' | 'default' | 'editor';

export { NodeKey }

declare type OfficePreviewKind = 'word' | 'cell' | 'slide' | 'pdf';

declare type OnPreviewOffice = (params: {
    fileId: string;
    kind: OfficePreviewKind;
    name: string;
}) => void;

declare type outputFormat = 'html' | 'json';

declare interface PageData {
    id: string;
    icon: string | null;
    title: string;
    order: number;
    onClick?: MouseEventHandler<HTMLDivElement>;
}

declare interface Pages {
    id: string;
    title: string;
    icon: string | null;
    order: number;
    children?: Pages[];
    onClick?: MouseEventHandler<HTMLDivElement>;
}

export { ParagraphNode }

export { PluginConfig }

export { RangeSelection }

export { ResizableContainer }

export declare type Root = SerializedEditorState<SerializedLexicalNode>;

export { RootNode }

declare type SerializedMarkNode = Spread<{
    ids: Array<string>;
}, SerializedElementNode>;

export { SlashMenuConfig }

export declare const StylesProvider: ({ children }: {
    children: React.ReactNode;
}) => JSX_2.Element;

export declare type SuccessDeleteImage = () => void;

export declare type SuccessUploadImage = (url: string, id: string, data?: UploadData) => void;

export { UploadData }

export { }
