/**
 * Document operations for DatabaseService
 *
 * Handles all CRUD operations for documents including
 * insert, get, list, update, and delete with cascade.
 */
import Database from 'better-sqlite3';
import { Document, DocumentStatus } from '../../../models/document.js';
import { ListDocumentsOptions } from './types.js';
/**
 * Encode a cursor from a (created_at, id) tuple.
 * Uses base64url encoding for URL-safe transport.
 *
 * @param createdAt - ISO 8601 timestamp
 * @param id - Document UUID
 * @returns Base64url-encoded cursor string
 */
export declare function encodeCursor(createdAt: string, id: string): string;
/**
 * Decode a cursor back to a (created_at, id) tuple.
 *
 * @param cursor - Base64url-encoded cursor string
 * @returns Decoded cursor with created_at and id
 * @throws Error if cursor is invalid or malformed
 */
export declare function decodeCursor(cursor: string): {
    created_at: string;
    id: string;
};
/**
 * Insert a new document
 *
 * @param db - Database connection
 * @param doc - Document data (created_at will be generated)
 * @param updateMetadataCounts - Callback to update metadata counts
 * @returns string - The document ID
 */
export declare function insertDocument(db: Database.Database, doc: Omit<Document, 'created_at'>, updateMetadataCounts: () => void): string;
/**
 * Get a document by ID
 *
 * @param db - Database connection
 * @param id - Document ID
 * @returns Document | null - The document or null if not found
 */
export declare function getDocument(db: Database.Database, id: string): Document | null;
/**
 * Get a document by file path
 *
 * @param db - Database connection
 * @param filePath - Full file path
 * @returns Document | null - The document or null if not found
 */
export declare function getDocumentByPath(db: Database.Database, filePath: string): Document | null;
/**
 * Get a document by file hash
 *
 * @param db - Database connection
 * @param fileHash - SHA-256 file hash
 * @returns Document | null - The document or null if not found
 */
export declare function getDocumentByHash(db: Database.Database, fileHash: string): Document | null;
/**
 * Result from listDocuments when cursor-based pagination is used
 */
export interface ListDocumentsResult {
    documents: Document[];
    /** Cursor for the next page (null if no more results) */
    next_cursor: string | null;
}
/**
 * List documents with optional filtering.
 *
 * Supports both offset-based and cursor-based pagination:
 * - When `cursor` is provided, uses keyset pagination (WHERE created_at < cursor.created_at
 *   OR (created_at = cursor.created_at AND id < cursor.id)) and ignores offset.
 * - When `cursor` is absent, uses traditional LIMIT/OFFSET.
 *
 * @param db - Database connection
 * @param options - Optional filter options (status, limit, offset, cursor)
 * @returns Document[] - Array of documents (backward-compatible)
 */
export declare function listDocuments(db: Database.Database, options?: ListDocumentsOptions): Document[];
/**
 * List documents with cursor-based pagination support.
 *
 * Returns both the documents and a next_cursor for fetching the next page.
 *
 * @param db - Database connection
 * @param options - Optional filter options (status, limit, offset, cursor)
 * @returns ListDocumentsResult with documents and next_cursor
 */
export declare function listDocumentsWithCursor(db: Database.Database, options?: ListDocumentsOptions): ListDocumentsResult;
/**
 * Update document status
 *
 * @param db - Database connection
 * @param id - Document ID
 * @param status - New status
 * @param errorMessage - Optional error message (for 'failed' status)
 * @param updateMetadataModified - Callback to update metadata modified timestamp
 */
export declare function updateDocumentStatus(db: Database.Database, id: string, status: DocumentStatus, errorMessage: string | undefined, updateMetadataModified: () => void): void;
/**
 * Update document when OCR completes
 *
 * @param db - Database connection
 * @param id - Document ID
 * @param pageCount - Number of pages processed
 * @param ocrCompletedAt - ISO 8601 completion timestamp
 * @param updateMetadataModified - Callback to update metadata modified timestamp
 */
export declare function updateDocumentOCRComplete(db: Database.Database, id: string, pageCount: number, ocrCompletedAt: string, updateMetadataModified: () => void): void;
/**
 * Update document metadata (title, author, subject) from OCR extraction
 *
 * @param db - Database connection
 * @param id - Document ID
 * @param metadata - Metadata fields to update (null values are ignored via COALESCE)
 * @param updateMetadataModified - Callback to update metadata modified timestamp
 */
export declare function updateDocumentMetadata(db: Database.Database, id: string, metadata: {
    docTitle?: string | null;
    docAuthor?: string | null;
    docSubject?: string | null;
}, updateMetadataModified: () => void): void;
/**
 * Shared cleanup: delete all derived records for a document.
 *
 * Deletion order (FK-safe):
 *   1. vec_embeddings (no inbound FKs)
 *   2. NULL images.vlm_embedding_id (break circular FK with embeddings)
 *   3. Re-queue orphaned images from other documents (VLM dedup)
 *   4. embeddings (covers chunk, VLM, and extraction types in one pass)
 *   5. images (safe after embeddings.image_id references gone)
 *   6. chunks
 *   7. extractions (before ocr_results: extractions.ocr_result_id -> ocr_results)
 *   8. ocr_results
 *   9. FTS metadata count updates (ids 1, 2, 3)
 *
 * @returns The number of embedding IDs deleted (for logging)
 */
export declare function deleteDerivedRecords(db: Database.Database, documentId: string, caller: string): number;
/**
 * Delete a document and all related data (CASCADE DELETE)
 *
 * @param db - Database connection
 * @param id - Document ID to delete
 * @param updateMetadataCounts - Callback to update metadata counts
 */
export declare function deleteDocument(db: Database.Database, id: string, updateMetadataCounts: () => void): void;
/**
 * Clean all derived data for a document, keeping the document record and its DOCUMENT-level provenance.
 *
 * Deletes: vec_embeddings, embeddings, images, chunks, ocr_results, and non-root provenance records.
 * This is used by retry_failed to reset a document to a clean "pending" state.
 *
 * @param db - Database connection
 * @param documentId - Document ID to clean
 */
export declare function cleanDocumentDerivedData(db: Database.Database, documentId: string): void;
//# sourceMappingURL=document-operations.d.ts.map