import type { ReactElement } from 'react';
import type { JSONDocNode } from '@atlaskit/editor-json-transformer';
import type { EditorState, ReadonlyTransaction, Transaction } from '@atlaskit/editor-prosemirror/state';
import type { Step } from '@atlaskit/editor-prosemirror/transform';
import { token } from '@atlaskit/tokens';
import type { Providers } from '../provider-factory';
export type NewCollabSyncUpErrorAttributes = {
    lengthOfUnconfirmedSteps?: number;
    tries: number;
    maxRetries: number;
    clientId?: number | string;
    version: number;
};
export type ResolvedEditorState<T = any> = {
    content: JSONDocNode | T;
    title: string | null;
    stepVersion: number;
};
export declare enum PROVIDER_ERROR_CODE {
    NO_PERMISSION_ERROR = "NO_PERMISSION_ERROR",
    INVALID_USER_TOKEN = "INVALID_USER_TOKEN",
    DOCUMENT_NOT_FOUND = "DOCUMENT_NOT_FOUND",
    LOCKED = "LOCKED",
    FAIL_TO_SAVE = "FAIL_TO_SAVE",
    DOCUMENT_RESTORE_ERROR = "DOCUMENT_RESTORE_ERROR",
    INITIALISATION_ERROR = "INITIALISATION_ERROR",
    NETWORK_ISSUE = "NETWORK_ISSUE",
    INVALID_PROVIDER_CONFIGURATION = "INVALID_PROVIDER_CONFIGURATION",
    INTERNAL_SERVICE_ERROR = "INTERNAL_SERVICE_ERROR",
    DOCUMENT_UPDATE_ERROR = "DOCUMENT_UPDATE_ERROR"
}
/**
 * This occurs when the provided user token is considered invalid for the given document ARI.
 * It happens during initialisation of the provider.
 * It could mean the document has been deleted (hence not found).
 * @message Message returned to editor, i.e User does not have permissions to access this document or document is not found
 * @recoverable It is recoverable, as we will try to refresh the token.
 */
type InsufficientEditingPermission = {
    code: PROVIDER_ERROR_CODE.NO_PERMISSION_ERROR;
    message: string;
    recoverable: boolean;
    reason?: string;
    /**
     * @deprecated switch to using either the error code or the recoverable flag
     */
    status?: number;
};
/**
 * Similar to InsufficientEditingPermission, but the user token is invalid because it has expired or been revoked.
 * It may also be an invalid token format.
 * This error is given to the provider by NCS.
 * @message Message returned to editor, i.e. The user token was invalid
 * @recoverable It is recoverable, as we will try to refresh the token.
 */
type InvalidUserToken = {
    code: PROVIDER_ERROR_CODE.INVALID_USER_TOKEN;
    message: string;
    recoverable: boolean;
    /**
     * @deprecated switch to using either the error code or the recoverable flag
     */
    status?: number;
};
/**
 * Document not found error, thrown when the provider is unable to find a document with the given ARI and user token.
 * It occurs during fetchCatchup, a function that fetches the latest document state during catchup.
 * We need to recieve a 404 from the document service to throw this error.
 * @message Message returned to editor, i.e. The requested document is not found
 * @recoverable It is recoverable, as the provider can try again later.
 */
type DocumentNotFound = {
    code: PROVIDER_ERROR_CODE.DOCUMENT_NOT_FOUND;
    message: string;
    recoverable: boolean;
    /**
     * @deprecated switch to using either the error code or the recoverable flag
     */
    status?: number;
};
/**
 * This error is thrown when the document is locked by another user.
 * The error is passed to us by NCS.
 * @message Message returned to editor, i.e. The document is currently not available, please try again later
 * @recoverable It is recoverable, as the provider can try again later.
 */
type Locked = {
    code: PROVIDER_ERROR_CODE.LOCKED;
    message: string;
    recoverable: boolean;
    status?: number;
};
/**
 * This error is thrown when the provider is unable to save the document.
 * This can happen when the connection to dynamoDB is lost, or when we do not have sufficient permissions (DYNAMO ERROR).
 * This error is given to us by NCS.
 * @message Message returned to editor, i.e. Collab service is not able to save changes
 * @recoverable It is not recoverable, as we don't want the user to continue editing a document that is not being saved.
 */
type FailToSave = {
    code: PROVIDER_ERROR_CODE.FAIL_TO_SAVE;
    message: string;
    recoverable: boolean;
    /**
     * @deprecated switch to using either the error code or the recoverable flag
     */
    status?: number;
};
/**
 * This error is thrown when the provider is unable to restore the document.
 * It occurs during onRestore, a function that restores the document to a previous version and reapplies unconfirmed steps.
 * onRestore is called when page recovery has emitted an 'init' event on a page client is currently connected to.
 * It could mean we failed to update the page metadata, or we failed to reapply unconfirmed steps.
 * @message Message returned to editor, i.e. Collab service unable to restore document
 * @recoverable It is not recoverable, as the provider has no further options after this.
 * The user will need to refresh the page to try again.
 */
type DocumentNotRestore = {
    code: PROVIDER_ERROR_CODE.DOCUMENT_RESTORE_ERROR;
    message: string;
    recoverable: boolean;
    /**
     * @deprecated switch to using either the error code or the recoverable flag
     */
    status?: number;
};
/**
 * The initial document couldn't be loaded from the collab service.
 * This error is given to us by NCS.
 * It could indicate either a network issue, or an internal service error in NCS.
 * @message Message returned to editor, i.e. The initial document couldn't be loaded from the collab service
 * @recoverable It is not recoverable, as the provider cannot do anything to fix it.
 * The user will need to refresh the page to try again.
 */
type InitialisationError = {
    code: PROVIDER_ERROR_CODE.INITIALISATION_ERROR;
    message: string;
    recoverable: boolean;
    /**
     * @deprecated switch to using either the error code or the recoverable flag
     */
    status?: number;
};
/**
 * Couldn't reconnect to the collab service (NCS) due to network issues.
 * NCS could be down, or the user could be offline. It's also possible the url is incorrect, or the user is behind a proxy blocking the connection.
 * Fired upon a reconnection attempt error (from Socket.IO Manager)
 * @message Message returned to editor, i.e. Couldn't reconnect to the collab service due to network issues
 * @recoverable It is recoverable, as the provider will try to reconnect.
 */
type NetworkIssue = {
    code: PROVIDER_ERROR_CODE.NETWORK_ISSUE;
    message: string;
    recoverable: boolean;
    /**
     * @deprecated switch to using either the error code or the recoverable flag
     */
    status?: number;
};
/**
 * This error is thrown when the provider has an invalid configuration.
 * It could happen due to these errors from NCS:
 *  NAMESPACE_INVALID
    INVALID_ACTIVATION_ID
    INVALID_DOCUMENT_ARI
    INVALID_CLOUD_ID
 * @message Message returned to editor, i.e. Invalid provider configuration
 * @recoverable It is not recoverable, as the provider cannot do anything to fix it.
 * The service using the provider will need to fix the configuration.
 */
type InvalidProviderConfiguration = {
    code: PROVIDER_ERROR_CODE.INVALID_PROVIDER_CONFIGURATION;
    message: string;
    recoverable: boolean;
    reason: string;
    /**
     * @deprecated switch to using either the error code or the recoverable flag
     */
    status?: number;
};
/**
 * This error is thrown when the provider encounters an internal service error, not otherwise accounted for.
 * @message Message returned to editor, i.e. Collab Provider experienced an unrecoverable error
 * @recoverable It is not recoverable, as the provider cannot do anything to fix it.
 */
type InternalServiceError = {
    code: PROVIDER_ERROR_CODE.INTERNAL_SERVICE_ERROR;
    message: string;
    recoverable: boolean;
    reason: string;
    /**
     * @deprecated switch to using either the error code or the recoverable flag
     */
    status?: number;
};
type ProviderDocumentUpdateError = {
    code: PROVIDER_ERROR_CODE.DOCUMENT_UPDATE_ERROR;
    message: 'The provider failed to apply changes to the editor';
    recoverable: boolean;
    /**
     * @deprecated switch to using either the error code or the recoverable flag
     */
    status?: number;
};
/**
 * A union of all possible provider errors that can be emitted back to the editor.
 */
export type ProviderError = InsufficientEditingPermission | InvalidUserToken | DocumentNotFound | Locked | FailToSave | DocumentNotRestore | InitialisationError | NetworkIssue | InvalidProviderConfiguration | InternalServiceError | ProviderDocumentUpdateError;
export interface Metadata {
    [key: string]: string | number | boolean;
}
export type CollabMetadataPayload = Metadata;
export interface CollabEventInitData {
    doc?: any;
    json?: any;
    version?: number;
    sid?: string;
    reserveCursor?: boolean;
}
export interface CollabInitPayload extends CollabEventInitData {
    doc: any;
    version: number;
    metadata?: Metadata;
    reserveCursor?: boolean;
}
export interface CollabEventConnectionData {
    sid: string;
    initial: boolean;
}
export type CollabConnectedPayload = CollabEventConnectionData;
export declare enum DisconnectReason {
    CLIENT_DISCONNECT = "CLIENT_DISCONNECT",
    SERVER_DISCONNECT = "SERVER_DISCONNECT",
    SOCKET_CLOSED = "SOCKET_CLOSED",
    SOCKET_ERROR = "SOCKET_ERROR",
    SOCKET_TIMEOUT = "SOCKET_TIMEOUT",
    UNKNOWN_DISCONNECT = "UNKNOWN_DISCONNECT"
}
export interface CollabDisconnectedPayload {
    reason: DisconnectReason;
    sid: string;
}
export interface CollabEventRemoteData {
    json?: any;
    newState?: EditorState;
    userIds?: (number | string)[];
}
type MarkJson = {
    type: string;
    attrs: {
        [key: string]: any;
    };
};
type NodeJson = {
    type: string;
    attrs: {
        [key: string]: any;
    };
    content: NodeJson[];
    marks: MarkJson[];
    text?: string;
};
type SliceJson = {
    content: NodeJson[];
    openStart: number;
    openEnd: number;
};
export type StepJson = {
    stepType?: string;
    from?: number;
    to?: number;
    slice?: SliceJson;
    clientId: number | string;
    userId: string;
    createdAt?: number;
    structure?: boolean;
};
export interface CollabDataPayload extends CollabEventRemoteData {
    version: number;
    json: StepJson[];
    userIds: (number | string)[];
}
export interface CollabSendableSelection {
    type: 'textSelection' | 'nodeSelection';
    anchor?: number | string;
    head?: number | string;
}
export interface CollabEventTelepointerData {
    type: 'telepointer';
    selection: CollabSendableSelection;
    sessionId: string;
}
export type CollabTelepointerPayload = CollabEventTelepointerData;
type ProviderParticipantPermitLevel = {
    isPermittedToView?: boolean;
    isPermittedToComment?: boolean;
    isPermittedToEdit?: boolean;
};
export interface CollabParticipant {
    lastActive: number;
    sessionId: string;
    avatar: string;
    name: string;
    cursorPos?: number;
    permit?: ProviderParticipantPermitLevel;
}
export type ProviderParticipant = CollabParticipant & {
    userId: string;
    clientId: number | string;
    email: string;
};
export interface CollabEventPresenceData {
    joined?: ProviderParticipant[];
    left?: {
        sessionId: string;
    }[];
}
export type CollabPresencePayload = CollabEventPresenceData;
export type CollabLocalStepsPayload = {
    steps: readonly Step[];
};
export interface CollabEventConnectingData {
    initial: boolean;
}
export type CollabConnectingPayload = CollabEventConnectingData;
export type CollabCommitStatusEventPayload = {
    status: 'attempt' | 'success' | 'failure';
    version: number;
};
export type UserPermitType = {
    isPermittedToView: boolean;
    isPermittedToComment: boolean;
    isPermittedToEdit: boolean;
};
export type CollabPermissionEventPayload = UserPermitType;
export interface CollabEvents {
    'metadata:changed': Metadata;
    init: CollabInitPayload;
    connected: CollabConnectedPayload;
    disconnected: CollabDisconnectedPayload;
    data: CollabDataPayload;
    telepointer: CollabTelepointerPayload;
    presence: CollabPresencePayload;
    'local-steps': CollabLocalStepsPayload;
    error: ProviderError;
    entity: any;
    connecting: CollabConnectingPayload;
    permission: CollabPermissionEventPayload;
    'commit-status': CollabCommitStatusEventPayload;
}
export type SyncUpErrorFunction = (attributes: NewCollabSyncUpErrorAttributes) => void;
export interface CollabEditProvider<Events extends CollabEvents = CollabEvents> {
    initialize(getState: () => any, createStep: (json: object) => Step): this;
    setup(props: {
        getState?: () => EditorState;
        onSyncUpError?: SyncUpErrorFunction;
    }): this;
    send(tr: Transaction, oldState: EditorState, newState: EditorState): void;
    on(evt: keyof Events, handler: (...args: any) => void): this;
    off(evt: keyof Events, handler: (...args: any) => void): this;
    unsubscribeAll(evt: keyof Events): this;
    sendMessage<K extends keyof Events>(data: {
        type: K;
    } & Events[K]): void;
    getFinalAcknowledgedState(): Promise<ResolvedEditorState>;
}
export type CollabEditOptions = {
    provider?: Providers['collabEditProvider'];
    userId?: string;
    useNativePlugin?: boolean;
} & CollabInviteToEditProps & CollabAnalyticsProps;
export type InviteToEditButtonProps = {
    onClick: (event: React.MouseEvent<HTMLElement>) => void;
    selected: boolean;
};
export type InviteToEditComponentProps = {
    children: ReactElement<InviteToEditButtonProps>;
};
export interface CollabInviteToEditProps {
    inviteToEditHandler?: (event: React.MouseEvent<HTMLElement>) => void;
    isInviteToEditButtonSelected?: boolean;
    inviteToEditComponent?: React.ComponentType<React.PropsWithChildren<InviteToEditComponentProps>>;
}
export interface CollabAnalyticsProps {
    /**
     * @description Control whether Synchrony entity error events are tracked
     */
    EXPERIMENTAL_allowInternalErrorAnalytics?: boolean;
}
export interface CollabEventLocalStepData {
    steps: Array<Step>;
}
export type Color = ReturnType<typeof token>;
export declare const TELEPOINTER_DIM_CLASS = "telepointer-dim";
export declare const telepointerStyle: import("@emotion/react").SerializedStyles;
export declare const isDirtyTransaction: (tr: Transaction | ReadonlyTransaction) => boolean;
export declare const tintDirtyTransaction: (tr: Transaction) => void;
export {};
