import React from 'react';
import { type Comment, type CommentAnchor, type CommentOutcome } from '../lib/comments-client.js';
import type { MentionUser } from '../lib/mention-picker.js';
/**
 * Side-panel view of the slice-4 comments API. Renders threaded comments
 * for a document, lets the current user compose new threads and replies,
 * and offers per-comment actions: edit, resolve / reopen, delete.
 *
 * The component is *pure I/O* against the comments-client module —
 * anchor encoding/decoding, editor mark painting, and bubble-menu wiring
 * are layered on top in `TipTapEditor.tsx` through the `comments` prop.
 * Keeping the panel logic agnostic of TipTap means the unit tests can
 * verify thread ordering / state transitions without spinning up an
 * editor.
 *
 * Behaviour
 * ─────────
 * - Active comments (not resolved, not deleted) are shown by default.
 * - A toggle reveals resolved threads in the same list, sorted by
 *   resolved-at descending so the most recently closed appears first.
 * - Composer accepts free-form text. When `onComposeAnchor` returns a
 *   non-null anchor the new comment is bound to that range; otherwise
 *   it is a document-level comment.
 * - The list refreshes after every successful mutation so optimistic
 *   state can't drift from the server.
 *
 * Errors fall through to the `onError` callback so the host shell can
 * surface them with its own toast / banner system (we don't import
 * sonner here to keep the component testable in plain JSDOM).
 */
export interface CommentSidePanelProps {
    documentId: string;
    /** Current user id — used to gate edit / delete affordances. */
    currentUserId: string;
    /** Set to `true` to show admin-only affordances (delete others'). */
    isAdmin?: boolean;
    /**
     * Called when the user clicks "Comment on selection". Should return
     * the encoded anchor for the active editor selection, or `null` for a
     * doc-level comment. Wiring lives in `TipTapEditor` so this component
     * stays editor-agnostic.
     */
    onComposeAnchor?: () => CommentAnchor | null;
    /**
     * Called whenever the active comment changes (focus shift / open
     * thread). The editor uses this to scroll the highlighted range into
     * view and paint the `actuate-comment--active` modifier.
     */
    onActiveCommentChange?: (commentId: string | null) => void;
    /** Error sink — bubble up server failures to a toast / banner. */
    onError?: (message: string) => void;
    /**
     * Override the comments-client API. Tests inject a fake; real callers
     * should leave this unset.
     */
    api?: CommentsApi;
    /**
     * Override the mention search — tests pass a synchronous fake so
     * the picker is deterministic without HTTP mocking. Production
     * callers leave this unset and the textarea uses the real
     * `/users/search` REST helper.
     */
    mentionSearch?: (query: string) => Promise<MentionUser[]>;
    className?: string;
}
/**
 * Tiny adapter type that lets tests swap the comments-client module out.
 * Mirrors the slice-4 client surface 1:1 — keeping it explicit prevents
 * accidental drift when new endpoints are added later.
 */
export interface CommentsApi {
    list: (documentId: string, opts?: {
        includeResolved?: boolean;
    }) => Promise<CommentOutcome<Comment[]>>;
    create: (input: {
        documentId: string;
        body: string;
        anchor?: CommentAnchor | null;
        parentId?: string | null;
    }) => Promise<CommentOutcome<Comment>>;
    update: (id: string, body: string) => Promise<CommentOutcome<Comment>>;
    resolve: (id: string) => Promise<CommentOutcome<Comment>>;
    reopen: (id: string) => Promise<CommentOutcome<Comment>>;
    remove: (id: string) => Promise<CommentOutcome<Comment>>;
}
export declare function CommentSidePanel({ documentId, currentUserId, isAdmin, onComposeAnchor, onActiveCommentChange, onError, api, mentionSearch, className, }: CommentSidePanelProps): React.JSX.Element;
/**
 * Cheap "n seconds / minutes / hours / days ago" formatter. We avoid
 * importing a full date-fns dependency just for this view; the panel is
 * fine being approximate.
 */
declare function formatRelative(iso: string): string;
export { formatRelative as _formatRelative };
//# sourceMappingURL=CommentSidePanel.d.ts.map