export type PageStatus = 'DRAFT' | 'PUBLISHED' | 'SCHEDULED' | 'ARCHIVED';
export declare const PAGES_COLLECTION = "pages";
export declare const PAGE_TAGS_COLLECTION = "page-tags";
export interface PageTag {
    id: string;
    docId: string;
    name: string;
    slug: string;
    description: string | null;
    color: string | null;
    pageCount: number;
    sortOrder: number;
    active: boolean;
    createdAt: string | null;
    updatedAt: string | null;
}
export interface PageAuthor {
    id: string;
    name: string;
    initials: string;
}
export interface Page {
    id: string;
    title: string;
    path: string;
    slug: string;
    parentPageId: string | null;
    tags: string[];
    primaryTagId: string | null;
    authorId: string;
    authorName: string;
    authorInitials: string;
    status: PageStatus;
    publishDate: string | null;
    scheduledDate: string | null;
    lastModified: string;
    seoScore: number | null;
    seoTitle: string | null;
    seoDescription: string | null;
    templateId: string | null;
    isHomepage: boolean;
    isSystemPage: boolean;
    createdAt: string;
    updatedAt: string;
}
export type PageGroupBy = 'none' | 'tag' | 'status' | 'author';
export interface PagesQuery {
    search?: string;
    tagIds?: string[];
    status?: PageStatus | 'all';
    authorId?: string | 'all';
    groupBy?: PageGroupBy;
    sortBy?: 'title' | 'author' | 'status' | 'modified' | 'seo';
    sortDirection?: 'asc' | 'desc';
    page?: number;
    pageSize?: number;
}
export interface PagesResult {
    pages: Page[];
    /** number of pages matching the active query (post-filter) */
    total: number;
    /** total pages in the collection, ignoring the active query/filters */
    grandTotal: number;
    page: number;
    pageSize: number;
    tags: PageTag[];
    authors: PageAuthor[];
}
/**
 * The full, unfiltered page set plus its tags and authors. The list view
 * fetches this once and applies search / sort / group / paging in memory
 * (see `applyPagesQuery` + `groupPages`), so typing in the search box or
 * changing the sort never re-downloads the dataset.
 */
export interface PagesDataset {
    pages: Page[];
    tags: PageTag[];
    authors: PageAuthor[];
}
/**
 * Fetch all tags. `pageCounts` (slug → count) is optional so the tag
 * manager / pickers can render before page data is loaded.
 */
export declare function fetchPageTags(pageCounts?: Map<string, number>): Promise<PageTag[]>;
export declare function fetchAuthors(): Promise<PageAuthor[]>;
/**
 * Pure filter+sort over an in-memory page set. Exported for unit tests
 * (keeps filtering logic decoupled from the network).
 */
export declare function applyPagesQuery(all: Page[], query: PagesQuery): Page[];
export interface PageGroup {
    key: string;
    label: string;
    color: string | null;
    pages: Page[];
}
/**
 * Group an already-filtered/sorted page list. A page appears in exactly
 * ONE group (no duplicates): for `tag`, its primary tag (or first tag,
 * or "Untagged"). Returns a single "All pages" group for `none`.
 */
export declare function groupPages(pages: Page[], groupBy: PageGroupBy, tags: PageTag[]): PageGroup[];
/**
 * Fetch the entire page dataset (unfiltered) plus tags and authors. This
 * is the single network read backing the list view; callers apply query
 * shaping in memory. Tag page counts and the author list are derived from
 * the full set so they reflect the dataset, not any active filter.
 */
export declare function fetchPagesDataset(): Promise<PagesDataset>;
/**
 * Query a paginated, filtered page list. Retained for non-list callers
 * (tag detach/merge) and tests; the list view uses `fetchPagesDataset`
 * directly and shapes the result in memory.
 */
export declare function fetchPages(query?: PagesQuery): Promise<PagesResult>;
export declare function fetchPageById(pageId: string): Promise<Page | null>;
export interface BulkResult {
    ok: number;
    failed: number;
}
export declare function bulkUpdatePages(ids: string[], payload: {
    status?: PageStatus;
    data?: Record<string, unknown>;
}): Promise<BulkResult>;
export declare function bulkDeletePages(ids: string[]): Promise<BulkResult>;
/**
 * Add or remove tag slugs across many pages. We fetch each page's
 * current tags, merge/strip, then PUT the new `data.tags`. Done
 * per-page because tags live in the document JSON (no bulk-tag endpoint
 * yet). `primaryTag` is cleared if it was removed.
 */
export declare function bulkChangePageTags(pages: Pick<Page, 'id' | 'tags' | 'primaryTagId'>[], change: {
    add?: string[];
    remove?: string[];
}): Promise<BulkResult>;
export interface PageTagInput {
    name: string;
    slug?: string;
    color?: string;
    description?: string;
    sortOrder?: number;
    active?: boolean;
}
export declare function createPageTag(input: PageTagInput): Promise<{
    error?: string;
}>;
export declare function updatePageTag(tagDocId: string, input: Partial<PageTagInput>): Promise<{
    error?: string;
}>;
export declare function deletePageTag(tagDocId: string): Promise<{
    error?: string;
}>;
/**
 * Delete a tag and detach it from every page that uses it (so no
 * dangling slugs remain in page `data.tags`). Used by the tag manager's
 * "remove from all pages" deletion path.
 */
export declare function deletePageTagWithDetach(tag: PageTag): Promise<{
    error?: string;
}>;
/**
 * Merge `source` into `target`: every page tagged with the source slug
 * gets the target slug (primary tag re-pointed too), then the source
 * tag document is deleted.
 */
export declare function mergePageTags(source: PageTag, target: PageTag): Promise<{
    error?: string;
}>;
//# sourceMappingURL=pages-service.d.ts.map