/**
 * Notion Document Sync Adapter
 *
 * Implements the DocumentSyncAdapter interface for Notion pages.
 * Converts between Stoneforge documents and Notion pages using the
 * Notion API client and the blocks ↔ markdown converter.
 *
 * Key operations:
 * - getPage: Fetch a page's properties and blocks, convert to ExternalDocument
 * - listPagesSince: Query a database for recently edited pages
 * - createPage: Convert markdown to Notion blocks, create page with properties
 * - updatePage: Update page properties and/or replace content blocks
 *
 * The adapter expects:
 * - `project` = Notion database ID
 * - `externalId` = Notion page ID
 *
 * Schema discovery:
 * The adapter discovers the database schema on first use via GET /databases/{id}.
 * Every Notion database has exactly one property of type "title", but its name
 * varies (common names: "Name", "Title"). The adapter discovers and caches this
 * name rather than hardcoding it.
 *
 * Optional properties (Category as select, Tags as multi_select, Library as
 * select) are only included in page properties when the database schema
 * confirms they exist. If they don't exist, the adapter attempts to auto-create
 * them via PATCH /databases/{id}. If that fails (e.g., insufficient
 * permissions), they are silently skipped.
 */
import type { DocumentSyncAdapter, ExternalDocument, ExternalDocumentInput } from '@stoneforge/core';
import type { Timestamp } from '@stoneforge/core';
import type { NotionProperty, NotionDatabaseSchema } from './notion-types.js';
import { NotionApiClient } from './notion-api.js';
/**
 * Extracts the title from a Notion page's properties.
 *
 * Searches through all properties for one of type 'title', then
 * concatenates the plain_text of all rich text elements within it.
 *
 * @param properties - The page's properties record
 * @returns The page title, or empty string if no title property is found
 */
export declare function extractTitleFromProperties(properties: Record<string, NotionProperty>): string;
/**
 * Builds Notion page properties for creating or updating a page.
 *
 * Uses the discovered database schema to:
 * - Set the title on the correct property (discovered name, not hardcoded)
 * - Only include Category, Tags, and Library if the database schema confirms they exist
 *
 * @param title - The page title
 * @param schema - The discovered database schema with property availability info
 * @param category - Optional category for the Category select property
 * @param tags - Optional tags for the Tags multi_select property
 * @param libraryPath - Optional library path for the Library select property
 * @returns A properties record suitable for the Notion API
 */
export declare function buildPageProperties(title: string, schema: NotionDatabaseSchema, category?: string, tags?: readonly string[], libraryPath?: string): Record<string, unknown>;
/**
 * DocumentSyncAdapter implementation for Notion.
 *
 * Uses the NotionApiClient for all API interactions and the
 * blocks ↔ markdown converter for content transformation.
 *
 * On first use of createPage() or updatePage(), the adapter discovers the
 * database schema to find the title property name and check which optional
 * properties exist. The schema is cached per database ID, so only one
 * getDatabase() call is made per adapter instance per database.
 *
 * @example
 * ```typescript
 * const api = new NotionApiClient({ token: 'ntn_...' });
 * const adapter = new NotionDocumentAdapter(api);
 *
 * // Fetch a page
 * const doc = await adapter.getPage('database-id', 'page-id');
 *
 * // List recently edited pages
 * const docs = await adapter.listPagesSince('database-id', '2024-01-01T00:00:00Z');
 *
 * // Create a new page (schema is discovered automatically)
 * const newDoc = await adapter.createPage('database-id', {
 *   title: 'New Page',
 *   content: '# Hello\n\nWorld',
 *   contentType: 'markdown',
 * });
 * ```
 */
export declare class NotionDocumentAdapter implements DocumentSyncAdapter {
    private readonly api;
    /** Cached database schemas keyed by database ID */
    private readonly schemaCache;
    constructor(api: NotionApiClient);
    /**
     * Discover and cache the database schema for a given database ID.
     *
     * Fetches the database schema from the Notion API, discovers the title
     * property name (every database has exactly one property of type 'title'),
     * and checks for the existence of Category (select), Tags (multi_select),
     * and Library (select) properties.
     *
     * If Category, Tags, or Library properties don't exist, attempts to
     * auto-create them via PATCH /databases/{id}. If the integration lacks
     * permission, the properties are simply skipped — no error is thrown.
     *
     * Results are cached per database ID so only one API call is made per
     * adapter instance per database.
     *
     * @param databaseId - The Notion database ID to discover
     * @returns The discovered database schema
     * @throws Error if the database has no title property
     */
    getDatabaseSchema(databaseId: string): Promise<NotionDatabaseSchema>;
    /**
     * Fetch a single page by its ID.
     *
     * Retrieves the page properties and block children, converts the blocks
     * to markdown, and returns a normalized ExternalDocument.
     *
     * @param project - The Notion database ID
     * @param externalId - The Notion page ID
     * @returns The page as an ExternalDocument, or null if not found
     */
    getPage(project: string, externalId: string): Promise<ExternalDocument | null>;
    /**
     * List pages in a database that have been edited since a given timestamp.
     *
     * Queries the database with a `last_edited_time > since` filter and
     * returns all matching pages as ExternalDocuments. Block content is
     * fetched for each page to build the full document.
     *
     * @param project - The Notion database ID
     * @param since - ISO 8601 timestamp to filter by last_edited_time
     * @returns Array of ExternalDocuments edited since the given time
     */
    listPagesSince(project: string, since: Timestamp): Promise<ExternalDocument[]>;
    /**
     * Create a new page in a Notion database.
     *
     * Discovers the database schema (if not cached), then converts the markdown
     * content to Notion blocks and creates a page with the discovered title
     * property name. Category (select) and Tags (multi_select) properties are
     * only set if they exist in the database schema.
     *
     * Notion limits POST /pages to 100 children blocks. If the content exceeds
     * this limit, the page is created with the first 100 blocks, and the
     * remaining blocks are appended in batches of 100 via PATCH /blocks/{id}/children.
     *
     * @param project - The Notion database ID
     * @param page - The document input with title and content
     * @returns The created page as an ExternalDocument
     */
    createPage(project: string, page: ExternalDocumentInput): Promise<ExternalDocument>;
    /**
     * Update an existing page's properties and/or content.
     *
     * If the updates include a title, the title property is updated using the
     * discovered property name from the database schema.
     * If the updates include content, all existing blocks are replaced
     * with new blocks converted from the updated markdown.
     *
     * @param project - The Notion database ID
     * @param externalId - The Notion page ID to update
     * @param updates - Partial updates to apply
     * @returns The updated page as an ExternalDocument
     */
    updatePage(project: string, externalId: string, updates: Partial<ExternalDocumentInput>): Promise<ExternalDocument>;
}
/**
 * Create a NotionDocumentAdapter from a NotionApiClient.
 *
 * @param api - A configured NotionApiClient
 * @returns A DocumentSyncAdapter for Notion
 */
export declare function createNotionDocumentAdapter(api: NotionApiClient): NotionDocumentAdapter;
//# sourceMappingURL=notion-document-adapter.d.ts.map