/**
 * Comments REST client — thin, typed wrapper around the
 * `/documents/:id/comments` + `/comments/:id` endpoints shipped in slice 4
 * of Phase 3 (see `packages/cms-core/src/realtime/comments.ts`).
 *
 * The client lives in `cms-admin` so the side panel, the bubble-menu
 * "comment on selection" action, and any future MCP/AI hooks all share one
 * request path, error model, and DTO shape.
 *
 * Mirrors the server contract:
 *   POST   /documents/:documentId/comments     -> { body, anchor?, parentId? }
 *   GET    /documents/:documentId/comments?…   -> { data: CommentDTO[] }
 *   PATCH  /comments/:id                       -> { body }
 *   POST   /comments/:id/resolve               -> 200 with updated DTO
 *   POST   /comments/:id/reopen                -> 200 with updated DTO
 *   DELETE /comments/:id                       -> 200 with soft-deleted DTO
 */
/**
 * Yjs relative-position anchor returned by the server. The encoding is
 * intentionally opaque on the wire (Base64 of `Y.encodeRelativePosition`);
 * `lib/comment-anchor.ts` handles the round-trip when slice 5 paints a
 * highlight in the editor.
 */
export interface CommentAnchor {
    from: string;
    to: string;
}
/**
 * Public DTO returned by every comments endpoint. Mirrors `CommentDTO` in
 * `@actuate-media/cms-core/realtime`; we duplicate the shape here so
 * `cms-admin` doesn't take a hard dependency on the server-side service
 * layer (which carries Prisma types we don't want pulled into the bundle).
 */
export interface Comment {
    id: string;
    documentId: string;
    parentId: string | null;
    userId: string | null;
    body: string;
    anchor: CommentAnchor | null;
    resolvedAt: string | null;
    resolvedById: string | null;
    deletedAt: string | null;
    createdAt: string;
    updatedAt: string;
    isResolved: boolean;
}
export type CommentOutcome<T> = {
    ok: true;
    result: T;
} | {
    ok: false;
    error: string;
    status: number;
};
export interface CreateCommentInput {
    documentId: string;
    body: string;
    anchor?: CommentAnchor | null;
    parentId?: string | null;
}
export interface ListCommentsOptions {
    /** Default: false. Resolved threads are filtered out unless requested. */
    includeResolved?: boolean;
    /** Default: false. Admin-only; the server rejects non-admin callers. */
    includeDeleted?: boolean;
    /** Default: server-side cap (100). Hard upper bound is 200. */
    pageSize?: number;
}
/**
 * Create a top-level comment or a reply. Pass `parentId` to thread the
 * comment under an existing one — the server enforces single-level
 * threading (replies cannot themselves be parents).
 */
export declare function createComment(input: CreateCommentInput): Promise<CommentOutcome<Comment>>;
/**
 * List comments for a document. Active comments (not resolved, not deleted)
 * are returned by default; pass `includeResolved` to keep resolved threads
 * in the response. The server rejects `includeDeleted` for non-admins.
 */
export declare function listComments(documentId: string, opts?: ListCommentsOptions): Promise<CommentOutcome<Comment[]>>;
/** Edit a comment body. Only the author or an admin is permitted. */
export declare function updateComment(id: string, body: string): Promise<CommentOutcome<Comment>>;
/** Resolve a thread. Write-role or the author may resolve. */
export declare function resolveComment(id: string): Promise<CommentOutcome<Comment>>;
/** Re-open a resolved thread. Same permission as resolve. */
export declare function reopenComment(id: string): Promise<CommentOutcome<Comment>>;
/**
 * Soft-delete a comment. The row is preserved so its replies don't lose
 * their thread root — the server simply stops returning it from the list
 * endpoint unless an admin asks for `includeDeleted`.
 */
export declare function deleteComment(id: string): Promise<CommentOutcome<Comment>>;
/**
 * Sort comments into thread groups suitable for rendering. Roots are
 * returned in chronological order; replies are ordered the same way and
 * attached to their root. Replies whose root is missing (e.g. the root was
 * filtered out by `includeResolved=false`) are dropped — the UI can fetch
 * them explicitly if it needs to render orphaned replies.
 */
export interface CommentThread {
    root: Comment;
    replies: Comment[];
}
export declare function groupCommentsIntoThreads(comments: readonly Comment[]): CommentThread[];
//# sourceMappingURL=comments-client.d.ts.map