import { Editor } from '@tiptap/react';
import { default as React } from 'react';
import { CommentAnchor } from '../extensions/comment/comment-decoration-plugin';
import { CommentFloatingCard, EnsCache, InlineCommentData, InlineCommentDraft, InlineDraftLocation } from '../components/inline-comment/context/types';
import { EnsStatus } from '../components/inline-comment/types';
import { IComment } from '../extensions/comment';
import { CommentMutationMeta, CommentMutationType } from '../types';

import * as Y from 'yjs';
export interface CommentExternalDeps {
    editor: Editor | null;
    ydoc: Y.Doc;
    setActiveCommentId: (id: string | null) => void;
    focusCommentWithActiveId: (id: string) => void;
    setInitialComments?: React.Dispatch<React.SetStateAction<IComment[]>>;
    setUsername?: React.Dispatch<React.SetStateAction<string>>;
    onNewComment?: (comment: IComment, meta?: CommentMutationMeta) => void;
    onEditComment?: (commentId: string, meta?: CommentMutationMeta) => void;
    onEditReply?: (commentId: string, replyId: string, meta?: CommentMutationMeta) => void;
    onCommentReply?: (activeCommentId: string, reply: IComment) => void;
    onResolveComment?: (commentId: string, meta?: CommentMutationMeta) => void;
    onUnresolveComment?: (commentId: string, meta?: CommentMutationMeta) => void;
    onDeleteComment?: (commentId: string, meta?: CommentMutationMeta) => void;
    onDeleteReply?: (commentId: string, replyId: string) => void;
    onInlineComment?: () => void;
    onComment?: () => void;
    setCommentDrawerOpen?: (open: boolean) => void;
    connectViaWallet?: () => Promise<void>;
    connectViaUsername?: (username: string) => Promise<void>;
    ensResolutionUrl: string;
    commentAnchorsRef?: React.MutableRefObject<CommentAnchor[]>;
    refreshCommentAnchorState?: () => void;
    /**
     * Derived anchor list for in-progress suggestion drafts. Maintained by the
     * store (not the consumer) — draft actions upsert into this ref whenever
     * state.drafts changes. The decoration extension reads this ref alongside
     * commentAnchorsRef to render both layers identically.
     */
    draftAnchorsRef?: React.MutableRefObject<CommentAnchor[]>;
}
/**
 * A suggestion draft is the viewer's in-progress proposed edit — kept local
 * until Submit. Drafts live in memory only (lost on refresh). Derived into
 * a CommentAnchor for decoration rendering via deriveDraftAnchor(). Most
 * suggestion types are derived at use time from hadDeletion + insertedText;
 * linkHref marks a link suggestion over the original selected text.
 */
export interface DraftSuggestion {
    id: string;
    anchorFrom: Y.RelativePosition;
    anchorTo: Y.RelativePosition;
    /** The text that was selected at draft creation (for Delete/Replace strikethrough). */
    originalContent: string;
    /** Accumulated text the viewer has typed. Empty for a pure Delete draft. */
    insertedText: string;
    /** Per-keystroke history for undo — each entry is one typed character. */
    keystrokes: string[];
    /** True when the draft was created via select+delete or select+type. */
    hadDeletion: boolean;
    /** Pasted link href for a link suggestion. */
    linkHref?: string;
}
type SuggestionDeleteDirection = 'backward' | 'forward';
export declare function isRangeDraft(draft: DraftSuggestion): boolean;
type FloatingCardsUpdater = React.SetStateAction<CommentFloatingCard[]>;
type InlineCommentDataUpdater = Partial<InlineCommentData> | ((prev: InlineCommentData) => Partial<InlineCommentData> | InlineCommentData);
type InlineDraftRecordMap = Record<string, InlineCommentDraft>;
type CreateInlineDraftOptions = {
    location?: InlineDraftLocation;
    tabId?: string;
    allowEmptySelection?: boolean;
};
type CommentEditRequest = {
    requestId: string;
    kind: 'comment' | 'reply';
    commentId: string;
    replyId?: string;
    text: string;
};
type ReplyEditTarget = {
    kind: 'comment' | 'reply';
    commentId: string;
    replyId?: string;
    originalText: string;
};
type CommentEditCompletion = {
    nonce: number;
    kind: 'comment' | 'reply';
    commentId: string;
    replyId?: string;
};
type FocusCommentInEditorOptions = {
    source?: 'explicit-ui' | 'passive';
};
type ReconcileFloatingThreadsForActiveTabOptions = {
    hydrationReady: boolean;
};
export declare const EXPLICIT_COMMENT_FOCUS_META = "inlineCommentExplicitFocus";
export interface CommentStoreState {
    initialComments: IComment[];
    tabComments: IComment[];
    activeComments: IComment[];
    activeComment: IComment | undefined;
    activeCommentIndex: number;
    username: string | null;
    activeCommentId: string | null;
    activeTabId: string;
    isConnected: boolean;
    isLoading: boolean;
    isDDocOwner: boolean;
    onComment: (() => void) | null;
    setCommentDrawerOpen: ((open: boolean) => void) | null;
    connectViaWallet: (() => Promise<void>) | null;
    connectViaUsername: ((username: string) => Promise<void>) | null;
    isCommentActive: boolean;
    isCommentResolved: boolean;
    showResolved: boolean;
    reply: string;
    comment: string;
    openReplyId: string | null;
    selectedText: string;
    isCommentOpen: boolean;
    isBubbleMenuSuppressed: boolean;
    inlineCommentData: InlineCommentData;
    floatingCards: CommentFloatingCard[];
    pendingPrehydrationFloatingThreadIds: string[];
    /** In-progress suggestion drafts — keyed by suggestionId. Viewer-local, lost on refresh. */
    drafts: Record<string, DraftSuggestion>;
    inlineDrafts: InlineDraftRecordMap;
    activeDraftId: string | null;
    isDesktopFloatingEnabled: boolean;
    ensCache: EnsCache;
    inProgressFetch: string[];
    editRequest: CommentEditRequest | null;
    replyEditTarget: ReplyEditTarget | null;
    editCompletion: CommentEditCompletion | null;
    _externalDepsRef: React.RefObject<CommentExternalDeps | null> | null;
    setExternalDepsRef: (ref: React.RefObject<CommentExternalDeps | null>) => void;
    _recomputeDerived: () => void;
    setInitialComments: (comments: IComment[]) => void;
    setUsername: (username: string | null) => void;
    setActiveCommentId: (id: string | null) => void;
    setActiveTabId: (tabId: string) => void;
    setIsConnected: (connected: boolean) => void;
    setIsLoading: (loading: boolean) => void;
    setIsDDocOwner: (isOwner: boolean) => void;
    setOnComment: (fn: (() => void) | null) => void;
    setCommentDrawerOpenFn: (fn: ((open: boolean) => void) | null) => void;
    setConnectViaWallet: (fn: (() => Promise<void>) | null) => void;
    setConnectViaUsername: (fn: ((username: string) => Promise<void>) | null) => void;
    setIsCommentActive: (active: boolean) => void;
    setIsCommentResolved: (resolved: boolean) => void;
    getTabComments: () => IComment[];
    getActiveComment: () => IComment | undefined;
    getActiveComments: () => IComment[];
    getActiveCommentIndex: () => number;
    getIsCommentActive: () => boolean;
    getIsCommentResolved: () => boolean;
    setShowResolved: (show: boolean) => void;
    setReply: (reply: string) => void;
    setComment: (comment: string) => void;
    setOpenReplyId: (id: string | null) => void;
    setSelectedText: (text: string) => void;
    setIsCommentOpen: (open: boolean) => void;
    setIsBubbleMenuSuppressed: (suppressed: boolean) => void;
    setInlineCommentData: (data: InlineCommentDataUpdater) => void;
    setFloatingCards: (floatingCards: FloatingCardsUpdater) => void;
    clearFloatingCards: () => void;
    setActiveDraftId: (draftId: string | null) => void;
    setIsDesktopFloatingEnabled: (enabled: boolean) => void;
    toggleResolved: () => void;
    clearEditRequest: (requestId: string) => void;
    setReplyEditTarget: (target: ReplyEditTarget | null) => void;
    cancelReplyEdit: () => void;
    handleInput: (e: React.FormEvent<HTMLTextAreaElement>, content: string) => void;
    handleReplyChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
    handleCommentChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
    handleCommentKeyDown: (e: React.KeyboardEvent<HTMLTextAreaElement>, tabId?: string) => void;
    handleReplyKeyDown: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void;
    handleReplySubmit: () => void;
    handleCommentSubmit: (tabId?: string) => void;
    handleInlineComment: () => void;
    addComment: (content?: string, usernameProp?: string) => string | undefined;
    createFloatingDraft: (options?: CreateInlineDraftOptions) => string | null;
    updateInlineDraftText: (draftId: string, value: string) => void;
    cancelInlineDraft: (draftId: string) => void;
    submitInlineDraft: (draftId: string) => void;
    updateFloatingDraftText: (draftId: string, value: string) => void;
    cancelFloatingDraft: (draftId: string) => void;
    submitFloatingDraft: (draftId: string) => void;
    openFloatingThread: (commentId: string) => void;
    focusSubmittedSuggestionFromEditor: (commentId: string) => boolean;
    closeFloatingCard: (floatingCardId: string) => void;
    blurFloatingCard: (floatingCardId: string) => void;
    focusFloatingCard: (floatingCardId: string) => void;
    removeInvalidFloatingDrafts: () => void;
    reconcileFloatingThreadsForActiveTab: (options: ReconcileFloatingThreadsForActiveTabOptions) => void;
    syncFloatingThreadCardWithActiveComment: () => void;
    submitPendingFloatingDrafts: () => void;
    /**
     * Apply anchor edits to local comment state.
     * Called after transaction analysis identifies edited anchors.
     * Updates selectedContent for each affected comment
     * so thread display stays in sync immediately, before consumer rehydration.
     */
    applyCommentAnchorEdits: (edits: Array<{
        commentId: string;
        selectedContent: string;
    }>) => void;
    resolveComment: (commentId: string) => void;
    unresolveComment: (commentId: string) => void;
    deleteComment: (commentId: string, options?: {
        skipExternalCallback?: boolean;
    }) => void;
    acceptSuggestion: (commentId: string) => void;
    /**
     * Append typed characters to the draft at the current cursor position.
     * Creates a new Add draft if no draft exists at the cursor.
     */
    appendToDraftAtCursor: (text: string) => void;
    /**
     * Create a Delete (or pending Replace) draft from a selection range.
     * Captures originalContent, leaves insertedText empty; type becomes 'replace'
     * as soon as the viewer types.
     */
    startDeleteDraft: (from: number, to: number, collapseTo?: number) => void;
    /**
     * Create a link suggestion from a selected range and pasted href.
     * The document stays unchanged until the owner accepts the suggestion.
     */
    startLinkDraft: (from: number, to: number, href: string) => void;
    /**
     * Convert a collapsed-caret Backspace/Delete into a delete draft when the
     * caret is adjacent to text, or shrink the active draft if the caret is
     * already inside one.
     */
    deleteAtCursorOrUndoActiveDraft: (direction: SuggestionDeleteDirection) => void;
    /**
     * Handle browser deletion paths that resolved to a concrete range even
     * though the user had no explicit selection.
     */
    deleteRangeOrUndoActiveDraft: (from: number, to: number) => void;
    /**
     * Undo the last keystroke in the draft at the current cursor position.
     * When the draft has no keystrokes left, it is discarded.
     * For a pure Delete draft (no keystrokes ever), calling this discards.
     */
    undoLastKeystrokeInActiveDraft: () => void;
    /** Drop a draft entirely — removes the inline overlay and draft card. */
    discardDraft: (suggestionId: string) => void;
    /**
     * Refresh the `originalContent` (and the suggestion-draft card's selectedText)
     * for a Delete/Replace draft whose anchored range still resolves but now
     * covers different text — happens when the owner edits within the anchored
     * range while the viewer's draft is open.
     */
    refreshDraftOriginalContent: (suggestionId: string, currentText: string) => void;
    /**
     * Promote a draft to a submitted suggestion. Pushes the anchor into
     * commentAnchorsRef, calls onNewComment, removes the draft, and swaps the
     * suggestion-draft floating card for a thread card (same floatingCardId).
     */
    submitDraft: (suggestionId: string) => void;
    deleteReply: (commentId: string, replyId: string) => void;
    requestEditComment: (commentId: string) => void;
    requestEditReply: (commentId: string, replyId: string) => void;
    editCommentContent: (commentId: string, content: string) => void;
    editReplyContent: (commentId: string, replyId: string, content: string) => void;
    handleAddReply: (activeCommentId: string, replyContent: string, replyCallback?: (activeCommentId: string, reply: IComment) => void) => void;
    focusCommentInEditor: (commentId: string, options?: FocusCommentInEditorOptions) => void;
    focusSuggestionDraftInEditor: (suggestionId: string) => void;
    onPrevComment: () => void;
    onNextComment: () => void;
    getEnsStatus: (walletAddress: string, setEnsStatus: React.Dispatch<React.SetStateAction<EnsStatus>>) => void;
    createMutationMeta: (type: CommentMutationType, mutate: () => boolean) => CommentMutationMeta | undefined;
}
export declare const createCommentStore: () => import('zustand').StoreApi<CommentStoreState>;
export declare const CommentStoreContext: React.Context<import('zustand').StoreApi<CommentStoreState> | null>;
export declare function useCommentStore<T>(selector: (state: CommentStoreState) => T): T;
export {};
