import { ObjectId, WithId, Document } from 'mongodb';
import { ModelQueryBuilder } from '../query_builder/model_query_builder.js';
import { ModelMetadata, ModelOperationOptions } from '../types/index.js';
import { type NamingStrategyContract } from '../naming_strategy/naming_strategy.js';
import type { MongoTransactionClient } from '../transaction_client.js';
/**
 * Type for create method attributes - includes all properties except methods, relationships, and BaseModel internals
 * Following AdonisJS Lucid pattern: computed properties and all data types are included
 */
import type { CreateAttributes } from '../types/embedded.js';
/**
 * Symbol to store model metadata
 */
export declare const MODEL_METADATA: unique symbol;
/**
 * Base Model class for MongoDB ODM
 */
export declare class BaseModel {
    /**
     * Naming strategy for the model
     * Defaults to CamelCaseNamingStrategy which converts camelCase to snake_case for serialization
     */
    static namingStrategy: NamingStrategyContract;
    /**
     * Indicates if the model instance exists in the database
     */
    $isPersisted: boolean;
    /**
     * Indicates if the model instance is local and not persisted
     */
    $isLocal: boolean;
    /**
     * Tracks modified properties
     */
    $dirty: Record<string, any>;
    /**
     * Original values before modifications
     */
    $original: Record<string, any>;
    /**
     * MongoDB document ID
     */
    _id?: ObjectId | string;
    /**
     * Transaction client for this model instance
     */
    $trx?: MongoTransactionClient;
    /**
     * Attribute manager instance
     */
    private $attributeManager;
    /**
     * Serialization manager instance
     */
    private $serializationManager;
    /**
     * Persistence manager instance
     */
    private $persistenceManager;
    constructor(attributes?: Record<string, any>);
    /**
     * Get model metadata
     */
    static getMetadata(): ModelMetadata;
    /**
     * Register a model in the global registry
     */
    static register(): void;
    /**
     * Get a model class from the registry
     */
    static getModelClass(modelName: string): typeof BaseModel | undefined;
    /**
     * Check if a model is registered
     */
    static hasModelClass(modelName: string): boolean;
    /**
     * Get all registered models
     */
    static getAllModels(): Map<string, typeof BaseModel>;
    /**
     * Clear the model registry (useful for testing)
     */
    static clearRegistry(): void;
    /**
     * Associate this model instance with a transaction
     */
    useTransaction(trx: MongoTransactionClient): this;
    /**
     * Get collection name for the model
     */
    static getCollectionName(): string;
    /**
     * Get connection name for the model
     */
    static getConnection(): string;
    /**
     * Create a new query builder instance with type-safe relationship loading
     */
    static query<T extends BaseModel = BaseModel>(this: typeof BaseModel & (new (...args: any[]) => T), options?: ModelOperationOptions): ModelQueryBuilder<Document, T>;
    /**
     * Find a document by its ID
     */
    static find<T extends BaseModel = BaseModel>(this: typeof BaseModel & (new (...args: any[]) => T), id: string | ObjectId, options?: ModelOperationOptions): Promise<T | null>;
    /**
     * Find a document by its ID or throw an exception
     */
    static findOrFail<T extends BaseModel>(this: typeof BaseModel & (new (...args: any[]) => T), id: string | ObjectId, options?: ModelOperationOptions): Promise<T>;
    /**
     * Find a document by a specific field
     */
    static findBy<T extends BaseModel>(this: typeof BaseModel & (new (...args: any[]) => T), field: string, value: any): Promise<T | null>;
    /**
     * Find a document by a specific field or throw an exception
     */
    static findByOrFail<T extends BaseModel>(this: typeof BaseModel & (new (...args: any[]) => T), field: string, value: any): Promise<T>;
    /**
     * Get the first document
     */
    static first<T extends BaseModel>(this: typeof BaseModel & (new (...args: any[]) => T)): Promise<T | null>;
    /**
     * Get the first document or throw an exception
     */
    static firstOrFail<T extends BaseModel>(this: typeof BaseModel & (new (...args: any[]) => T)): Promise<T>;
    /**
     * Get all documents
     */
    static all<T extends BaseModel>(this: typeof BaseModel & (new (...args: any[]) => T)): Promise<T[]>;
    /**
     * Create a new document
     */
    static create<T extends BaseModel>(this: new (...args: any[]) => T, attributes: CreateAttributes<T>, options?: ModelOperationOptions): Promise<T>;
    /**
     * Create multiple documents
     */
    static createMany<T extends BaseModel>(this: new (...args: any[]) => T, attributesArray: CreateAttributes<T>[]): Promise<T[]>;
    /**
     * Update or create a document
     */
    static updateOrCreate<T extends BaseModel>(this: new (...args: any[]) => T, searchPayload: CreateAttributes<T>, persistencePayload: CreateAttributes<T>): Promise<T>;
    /**
     * Fill the model with attributes
     */
    fill(attributes: Record<string, any>): this;
    /**
     * Merge new attributes into the model
     */
    merge(attributes: Record<string, any>): this;
    /**
     * Save the model to the database
     */
    save(): Promise<this>;
    /**
     * Delete the model from the database
     */
    delete(): Promise<boolean>;
    /**
     * Get an attribute value
     */
    getAttribute(key: string): any;
    /**
     * Set an attribute value
     */
    setAttribute(key: string, value: any): void;
    /**
     * Hydrate the model from a MongoDB document
     * Handles conversion from database column names (snake_case) back to model properties (camelCase)
     */
    hydrateFromDocument(document: WithId<Document>): void;
    /**
     * Convert the model to a plain object for database storage
     * Following AdonisJS Lucid naming strategy (camelCase -> snake_case by default)
     */
    toDocument(): Record<string, any>;
    /**
     * Convert the model to a plain object for JSON serialization (API responses)
     * This includes computed properties and properly serializes relationships
     * Following AdonisJS Lucid naming strategy (camelCase -> snake_case by default)
     */
    toJSON(): Record<string, any>;
    /**
     * Get dirty attributes for the model
     * Returns attributes with database column names (snake_case) for database operations
     */
    getDirtyAttributes(): Record<string, any>;
    /**
     * Sync the original values with current values
     */
    syncOriginal(): void;
    /**
     * Initialize relationship proxies for Lucid-style property access
     * Note: Relationship proxies are now created directly by the decorators
     */
    private initializeRelationshipProxies;
}
//# sourceMappingURL=base_model.d.ts.map