declare type actionWithDelay = {
    doAction: () => void;
    delay: number;
};

declare type addedNodeMutation = {
    parentId: number;
    previousId?: number | null;
    nextId: number | null;
    node: serializedNodeWithId;
};

declare type adoptedStyleSheetCallback = (a: adoptedStyleSheetParam) => void;

declare type adoptedStyleSheetData = {
    source: IncrementalSource.AdoptedStyleSheet;
} & adoptedStyleSheetParam;

declare type adoptedStyleSheetParam = {
    id: number;
    styles?: {
        styleId: number;
        rules: styleSheetAddRule[];
    }[];
    styleIds: number[];
};

declare type Arguments<T> = T extends (...payload: infer U) => unknown ? U : unknown;

declare type attributeCursor = {
    node: Node;
    attributes: {
        [key: string]: string | styleOMValue | null;
    };
    styleDiff: styleOMValue;
    _unchangedStyles: styleOMValue;
};

declare type attributeMutation = {
    id: number;
    attributes: {
        [key: string]: string | styleOMValue | null;
    };
};

declare type attributes = cssTextKeyAttr & {
    [key: string]: string | number | true | null;
};

declare type blockClass = string | RegExp;

declare type CanvasArg = SerializedCanvasArg | string | number | boolean | null | CanvasArg[];

declare enum CanvasContext {
    '2D' = 0,
    WebGL = 1,
    WebGL2 = 2
}

declare type canvasEventWithTime = eventWithTime & {
    type: EventType.IncrementalSnapshot;
    data: canvasMutationData;
};

declare type canvasManagerMutationCallback = (target: HTMLCanvasElement, p: canvasMutationWithType) => void;

declare type canvasMutationCallback = (p: canvasMutationParam) => void;

declare type canvasMutationCommand = {
    property: string;
    args: Array<unknown>;
    setter?: true;
};

declare type canvasMutationData = {
    source: IncrementalSource.CanvasMutation;
} & canvasMutationParam;

declare type canvasMutationParam = {
    id: number;
    type: CanvasContext;
    commands: canvasMutationCommand[];
    displayWidth?: number;
    displayHeight?: number;
} | ({
    id: number;
    type: CanvasContext;
    displayWidth?: number;
    displayHeight?: number;
} & canvasMutationCommand);

declare type canvasMutationWithType = {
    type: CanvasContext;
} & canvasMutationCommand;

declare type cdataNode = {
    type: NodeType.CDATA;
    textContent: '';
};

declare type commentNode = {
    type: NodeType.Comment;
    textContent: string;
};

declare type cssTextKeyAttr = {
    _cssText?: string;
};

declare type customElementCallback = (c: customElementParam) => void;

declare type customElementData = {
    source: IncrementalSource.CustomElement;
} & customElementParam;

declare type customElementParam = {
    define?: {
        name: string;
    };
};

declare type customEvent<T = unknown> = {
    type: EventType.Custom;
    data: {
        tag: string;
        payload: T;
    };
};

declare type DataURLOptions = Partial<{
    type: string;
    quality: number;
    maxBase64ImageLength: number;
}>;

declare type DeprecatedMirror = {
    map: {
        [key: number]: INode;
    };
    getId: (n: Node) => number;
    getNode: (id: number) => INode | null;
    removeNodeFromMap: (n: Node) => void;
    has: (id: number) => boolean;
    reset: () => void;
};

declare type DocumentDimension = {
    x: number;
    y: number;
    relativeScale: number;
    absoluteScale: number;
};

declare type documentNode = {
    type: NodeType.Document;
    childNodes: serializedNodeWithId[];
    compatMode?: string;
};

declare type documentTypeNode = {
    type: NodeType.DocumentType;
    name: string;
    publicId: string;
    systemId: string;
};

declare type domContentLoadedEvent = {
    type: EventType.DomContentLoaded;
    data: unknown;
};

declare type elementNode = {
    type: NodeType.Element;
    tagName: string;
    attributes: attributes;
    childNodes: serializedNodeWithId[];
    isSVG?: true;
    needBlock?: boolean;
    isCustom?: true;
};

declare type Emitter = {
    on(type: string, handler: Handler): void;
    emit(type: string, event?: unknown): void;
    off(type: string, handler: Handler): void;
};

declare type event_2 = eventWithoutTime;


declare enum EventType {
    DomContentLoaded = 0,
    Load = 1,
    FullSnapshot = 2,
    IncrementalSnapshot = 3,
    Meta = 4,
    Custom = 5,
    Plugin = 6
}

declare type eventWithoutTime = domContentLoadedEvent | loadedEvent | fullSnapshotEvent | incrementalSnapshotEvent | metaEvent | customEvent | pluginEvent;

declare type eventWithTime = eventWithoutTime & {
    timestamp: number;
    delay?: number;
};

declare type fontCallback = (p: fontParam) => void;

declare type fontData = {
    source: IncrementalSource.Font;
} & fontParam;

declare type fontParam = {
    family: string;
    fontSource: string;
    buffer: boolean;
    descriptors?: FontFaceDescriptors;
};

declare const FullscreenCustomEventTag = "rrweb/fullscreen";

declare type fullscreenEventPayload = {
    id: number;
    enter: boolean;
};

declare type fullSnapshotEvent = {
    type: EventType.FullSnapshot;
    data: {
        node: serializedNodeWithId;
        initialOffset: {
            top: number;
            left: number;
        };
    };
};

declare type GetTypedKeys<Obj extends object, ValueType> = TakeTypeHelper<Obj, ValueType>[keyof TakeTypeHelper<Obj, ValueType>];

declare type Handler = (event?: unknown) => void;

declare type hookResetter = () => void;

declare type hooksParam = {
    mutation?: mutationCallBack;
    mousemove?: mousemoveCallBack;
    mouseInteraction?: mouseInteractionCallBack;
    scroll?: scrollCallback;
    viewportResize?: viewportResizeCallback;
    input?: inputCallback;
    mediaInteaction?: mediaInteractionCallback;
    styleSheetRule?: styleSheetRuleCallback;
    styleDeclaration?: styleDeclarationCallback;
    canvasMutation?: canvasMutationCallback;
    font?: fontCallback;
    selection?: selectionCallback;
    customElement?: customElementCallback;
};

declare interface ICrossOriginIframeMirror {
    getId(iframe: HTMLIFrameElement, remoteId: number, parentToRemoteMap?: Map<number, number>, remoteToParentMap?: Map<number, number>): number;
    getIds(iframe: HTMLIFrameElement, remoteId: number[]): number[];
    getRemoteId(iframe: HTMLIFrameElement, parentId: number, map?: Map<number, number>): number;
    getRemoteIds(iframe: HTMLIFrameElement, parentId: number[]): number[];
    reset(iframe?: HTMLIFrameElement): void;
}

declare type ImageBitmapDataURLWorkerParams = {
    id: number;
    bitmap: ImageBitmap;
    width: number;
    height: number;
    dataURLOptions: DataURLOptions;
};

declare type ImageBitmapDataURLWorkerResponse = {
    id: number;
} | {
    id: number;
    type: string;
    base64: string;
    width: number;
    height: number;
};

declare interface IMirror<TNode> {
    getId(n: TNode | undefined | null): number;
    getNode(id: number): TNode | null;
    getIds(): number[];
    getMeta(n: TNode): serializedNodeWithId | null;
    removeNodeFromMap(n: TNode): void;
    has(id: number): boolean;
    hasNode(node: TNode): boolean;
    add(n: TNode, meta: serializedNodeWithId): void;
    replace(id: number, n: TNode): void;
    reset(): void;
}

declare type incrementalData = mutationData | mousemoveData | mouseInteractionData | scrollData | viewportResizeData | inputData | mediaInteractionData | styleSheetRuleData | canvasMutationData | fontData | selectionData | styleDeclarationData | adoptedStyleSheetData | customElementData;

declare type incrementalSnapshotEvent = {
    type: EventType.IncrementalSnapshot;
    data: incrementalData;
};

declare enum IncrementalSource {
    Mutation = 0,
    MouseMove = 1,
    MouseInteraction = 2,
    Scroll = 3,
    ViewportResize = 4,
    Input = 5,
    TouchMove = 6,
    MediaInteraction = 7,
    StyleSheetRule = 8,
    CanvasMutation = 9,
    Font = 10,
    Log = 11,
    Drag = 12,
    StyleDeclaration = 13,
    Selection = 14,
    AdoptedStyleSheet = 15,
    CustomElement = 16
}

declare interface INode extends Node {
    __sn: serializedNodeWithId;
}

declare type inputCallback = (v: inputValue & {
    id: number;
}) => void;

declare type inputData = {
    source: IncrementalSource.Input;
    id: number;
} & inputValue;

declare type inputValue = {
    text: string;
    isChecked: boolean;
    userTriggered?: boolean;
};

declare type IWindow = Window & typeof globalThis;

declare type KeepIframeSrcFn = (src: string) => boolean;

declare type legacyAttributes = {
    selected: false;
};

declare type listenerHandler = () => void;

declare type loadedEvent = {
    type: EventType.Load;
    data: unknown;
};

declare type maskTextClass = string | RegExp;

declare type mediaAttributes = {
    rr_mediaState: 'played' | 'paused';
    rr_mediaCurrentTime: number;
    rr_mediaPlaybackRate?: number;
    rr_mediaMuted?: boolean;
    rr_mediaLoop?: boolean;
    rr_mediaVolume?: number;
};

declare type mediaInteractionCallback = (p: mediaInteractionParam) => void;

declare type mediaInteractionData = {
    source: IncrementalSource.MediaInteraction;
} & mediaInteractionParam;

declare type mediaInteractionParam = {
    type: MediaInteractions;
    id: number;
    currentTime?: number;
    volume?: number;
    muted?: boolean;
    loop?: boolean;
    playbackRate?: number;
};

declare enum MediaInteractions {
    Play = 0,
    Pause = 1,
    Seeked = 2,
    VolumeChange = 3,
    RateChange = 4
}

declare type metaEvent = {
    type: EventType.Meta;
    data: {
        href: string;
        width: number;
        height: number;
    };
};

declare type mouseInteractionCallBack = (d: mouseInteractionParam) => void;

declare type mouseInteractionData = {
    source: IncrementalSource.MouseInteraction;
} & mouseInteractionParam;

declare type mouseInteractionParam = {
    type: MouseInteractions;
    id: number;
    x?: number;
    y?: number;
    pointerType?: PointerTypes;
};

declare enum MouseInteractions {
    MouseUp = 0,
    MouseDown = 1,
    Click = 2,
    ContextMenu = 3,
    DblClick = 4,
    Focus = 5,
    Blur = 6,
    TouchStart = 7,
    TouchMove_Departed = 8,
    TouchEnd = 9,
    TouchCancel = 10
}

declare type mousemoveCallBack = (p: mousePosition[], source: IncrementalSource.MouseMove | IncrementalSource.TouchMove | IncrementalSource.Drag) => void;

declare type mousemoveData = {
    source: IncrementalSource.MouseMove | IncrementalSource.TouchMove | IncrementalSource.Drag;
    positions: mousePosition[];
};

declare type mouseMovePos = {
    x: number;
    y: number;
    id: number;
    debugData: incrementalData;
};

declare type mousePosition = {
    x: number;
    y: number;
    id: number;
    timeOffset: number;
};

declare type mutationCallBack = (m: mutationCallbackParam) => void;

declare type mutationCallbackParam = {
    texts: textMutation[];
    attributes: attributeMutation[];
    removes: removedNodeMutation[];
    adds: addedNodeMutation[];
    isAttachIframe?: true;
};

declare type mutationData = {
    source: IncrementalSource.Mutation;
} & mutationCallbackParam;

declare type mutationRecord = Readonly<{
    type: string;
    target: Node;
    oldValue: string | null;
    addedNodes: NodeList;
    removedNodes: NodeList;
    attributeName: string | null;
}>;

declare enum NodeType {
    Document = 0,
    DocumentType = 1,
    Element = 2,
    Text = 3,
    CDATA = 4,
    Comment = 5
}

declare type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;

declare type PackFn = (event: eventWithTime) => string;

declare type playerMetaData = {
    startTime: number;
    endTime: number;
    totalTime: number;
};

declare type pluginEvent<T = unknown> = {
    type: EventType.Plugin;
    data: {
        plugin: string;
        payload: T;
    };
};

declare enum PointerTypes {
    Mouse = 0,
    Pen = 1,
    Touch = 2
}

declare type RecordPlugin<TOptions = unknown> = {
    name: string;
    observer?: (cb: (...args: Array<unknown>) => void, win: IWindow, options: TOptions) => listenerHandler;
    eventProcessor?: <TExtend>(event: eventWithTime) => eventWithTime & TExtend;
    getMirror?: (mirrors: {
        nodeMirror: IMirror<Node>;
        crossOriginIframeMirror: ICrossOriginIframeMirror;
        crossOriginIframeStyleMirror: ICrossOriginIframeMirror;
    }) => void;
    options: TOptions;
};

declare type removedNodeMutation = {
    parentId: number;
    id: number;
    isShadow?: boolean;
};

declare enum ReplayerEvents {
    Start = "start",
    Pause = "pause",
    Resume = "resume",
    Resize = "resize",
    Finish = "finish",
    FullsnapshotRebuilded = "fullsnapshot-rebuilded",
    LoadStylesheetStart = "load-stylesheet-start",
    LoadStylesheetEnd = "load-stylesheet-end",
    SkipStart = "skip-start",
    SkipEnd = "skip-end",
    MouseInteraction = "mouse-interaction",
    EventCast = "event-cast",
    CustomEvent = "custom-event",
    Flush = "flush",
    StateChange = "state-change",
    PlayBack = "play-back",
    Destroy = "destroy"
}

declare type SamplingStrategy = Partial<{
    mousemove: boolean | number;
    mousemoveCallback: number;
    mouseInteraction: boolean | Record<string, boolean | undefined>;
    scroll: number;
    media: number;
    input: 'all' | 'last';
    canvas: 'all' | number;
}>;

declare type scrollCallback = (p: scrollPosition) => void;

declare type scrollData = {
    source: IncrementalSource.Scroll;
} & scrollPosition;

declare type scrollPosition = {
    id: number;
    x: number;
    y: number;
};

declare type selectionCallback = (p: selectionParam) => void;

declare type selectionData = {
    source: IncrementalSource.Selection;
} & selectionParam;

declare type selectionParam = {
    ranges: Array<SelectionRange>;
};

declare type SelectionRange = {
    start: number;
    startOffset: number;
    end: number;
    endOffset: number;
};

declare type SerializedCanvasArg = {
    rr_type: 'ArrayBuffer';
    base64: string;
} | {
    rr_type: 'Blob';
    data: Array<CanvasArg>;
    type?: string;
} | {
    rr_type: string;
    src: string;
} | {
    rr_type: string;
    args: Array<CanvasArg>;
} | {
    rr_type: string;
    index: number;
};

declare type serializedElementNodeWithId = Extract<serializedNodeWithId, Record<'type', NodeType.Element>>;

declare type serializedNode = (documentNode | documentTypeNode | elementNode | textNode | cdataNode | commentNode) & {
    rootId?: number;
    isShadowHost?: boolean;
    isShadow?: boolean;
};

declare type serializedNodeWithId = serializedNode & {
    id: number;
};

declare type styleDeclarationCallback = (s: styleDeclarationParam) => void;

declare type styleDeclarationData = {
    source: IncrementalSource.StyleDeclaration;
} & styleDeclarationParam;

declare type styleDeclarationParam = {
    id?: number;
    styleId?: number;
    index: number[];
    set?: {
        property: string;
        value: string | null;
        priority: string | undefined;
    };
    remove?: {
        property: string;
    };
};

declare type styleOMValue = {
    [key: string]: styleValueWithPriority | string | false;
};

declare type styleSheetAddRule = {
    rule: string;
    index?: number | number[];
};

declare type styleSheetDeleteRule = {
    index: number | number[];
};

declare type styleSheetRuleCallback = (s: styleSheetRuleParam) => void;

declare type styleSheetRuleData = {
    source: IncrementalSource.StyleSheetRule;
} & styleSheetRuleParam;

declare type styleSheetRuleParam = {
    id?: number;
    styleId?: number;
    removes?: styleSheetDeleteRule[];
    adds?: styleSheetAddRule[];
    replace?: string;
    replaceSync?: string;
};

declare type styleValueWithPriority = [string, string];

declare type TakeTypedKeyValues<Obj extends object, Type> = Pick<Obj, TakeTypeHelper<Obj, Type>[keyof TakeTypeHelper<Obj, Type>]>;

declare type TakeTypeHelper<Obj extends object, ValueType> = {
    [K in keyof Obj]: Obj[K] extends ValueType ? K : never;
};

declare type textCursor = {
    node: Node;
    value: string | null;
};

declare type textMutation = {
    id: number;
    value: string | null;
};

declare type textNode = {
    type: NodeType.Text;
    textContent: string;
    isStyle?: true;
};

declare type throttleOptions = {
    leading?: boolean;
    trailing?: boolean;
};

declare type UnpackFn = (raw: string) => eventWithTime;

declare type viewportResizeCallback = (d: viewportResizeDimension) => void;

declare type viewportResizeData = {
    source: IncrementalSource.ViewportResize;
} & viewportResizeDimension;

declare type viewportResizeDimension = {
    width: number;
    height: number;
};

export { CanvasContext, EventType, FullscreenCustomEventTag, IncrementalSource, MediaInteractions, MouseInteractions, NodeType, PointerTypes, ReplayerEvents };
export type { Arguments, CanvasArg, DataURLOptions, DeprecatedMirror, DocumentDimension, Emitter, GetTypedKeys, Handler, ICrossOriginIframeMirror, IMirror, IWindow, ImageBitmapDataURLWorkerParams, ImageBitmapDataURLWorkerResponse, KeepIframeSrcFn, Optional, PackFn, RecordPlugin, SamplingStrategy, SelectionRange, SerializedCanvasArg, TakeTypeHelper, TakeTypedKeyValues, UnpackFn, actionWithDelay, addedNodeMutation, adoptedStyleSheetCallback, adoptedStyleSheetData, adoptedStyleSheetParam, attributeCursor, attributeMutation, attributes, blockClass, canvasEventWithTime, canvasManagerMutationCallback, canvasMutationCallback, canvasMutationCommand, canvasMutationData, canvasMutationParam, canvasMutationWithType, cdataNode, commentNode, customElementCallback, customElementData, customElementParam, customEvent, documentNode, documentTypeNode, domContentLoadedEvent, elementNode, event_2 as event, eventWithTime, eventWithoutTime, fontCallback, fontData, fontParam, fullSnapshotEvent, fullscreenEventPayload, hookResetter, hooksParam, incrementalData, incrementalSnapshotEvent, inputCallback, inputData, inputValue, legacyAttributes, listenerHandler, loadedEvent, maskTextClass, mediaAttributes, mediaInteractionCallback, mediaInteractionData, mediaInteractionParam, metaEvent, mouseInteractionCallBack, mouseInteractionData, mouseMovePos, mousePosition, mousemoveCallBack, mousemoveData, mutationCallBack, mutationCallbackParam, mutationData, mutationRecord, playerMetaData, pluginEvent, removedNodeMutation, scrollCallback, scrollData, scrollPosition, selectionCallback, selectionData, selectionParam, serializedElementNodeWithId, serializedNode, serializedNodeWithId, styleDeclarationCallback, styleDeclarationData, styleDeclarationParam, styleOMValue, styleSheetAddRule, styleSheetDeleteRule, styleSheetRuleCallback, styleSheetRuleData, styleSheetRuleParam, styleValueWithPriority, textCursor, textMutation, textNode, throttleOptions, viewportResizeCallback, viewportResizeData, viewportResizeDimension };
