/**
 * @athenna/database
 *
 * (c) João Lenon <lenon@athenna.io>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
import { Collection, type PaginatedResponse, type PaginationOptions } from '@athenna/common';
import { type Faker } from '@faker-js/faker';
import { ModelSchema } from '#src/models/schemas/ModelSchema';
import type { ModelColumns, ModelRelations } from '#src/types';
import { ORIGINAL_SYMBOL } from '#src/constants/OriginalSymbol';
import { ModelFactory } from '#src/models/factories/ModelFactory';
import { ModelQueryBuilder } from '#src/models/builders/ModelQueryBuilder';
export declare class BaseModel {
    /**
     * Set if the `attributes` method should be called or not.
     */
    private static get isToSetAttributes();
    /**
     * Set if the option annotation `isUnique`
     * should be verified or not.
     */
    private static get isToValidateUnique();
    /**
     * Set if the option annotation `isNullable`
     * should be verified or not.
     */
    private static get isToValidateNullable();
    /**
     * The faker instance to create fake data in
     * definition instance.
     */
    static get faker(): Faker;
    /**
     * Set the connection name that model will use
     * to access database.
     */
    static connection(): any;
    /**
     * Set if model should automatically be sync with
     * database when running DatabaseProvider.
     *
     * @default true
     */
    static sync(): boolean;
    /**
     * Set the table name of this model instance.
     */
    static table(): string;
    /**
     * Set the default values that should be set when creating or
     * updating the model.
     */
    static attributes(): Record<string, unknown>;
    /**
     * Set the definition data that will be used when fabricating
     * instances of your model using factories.
     */
    static definition(): Promise<Record<string, unknown>>;
    /**
     * Create a new ModelSchema instance from your model.
     */
    static schema<T extends typeof BaseModel>(this: T): ModelSchema<InstanceType<T>>;
    /**
     * Create a new ModelFactory instance from your model.
     */
    static factory<T extends typeof BaseModel>(this: T): ModelFactory<InstanceType<T>, InstanceType<T>>;
    /**
     * Enable/disable setting the default attributes properties
     * when creating/updating models.
     */
    static setAttributes<T extends typeof BaseModel>(this: T, value: boolean): T;
    /**
     * Enable/disable the `isUnique` property validation of
     * models columns.
     */
    static uniqueValidation<T extends typeof BaseModel>(this: T, value: boolean): T;
    /**
     * Enable/disable the `isNullable` property validation of
     * models columns.
     */
    static nullableValidation<T extends typeof BaseModel>(this: T, value: boolean): T;
    /**
     * Create a query builder for the model.
     */
    static query<T extends typeof BaseModel>(this: T): ModelQueryBuilder<InstanceType<T>, import("../database/drivers/MongoDriver.js").MongoDriver>;
    /**
     * Remove all data inside model table
     * and restart the identity of the table.
     */
    static truncate(): Promise<void>;
    /**
     * Find value in database but returns only the value of
     * selected column directly.
     */
    static pluck<T extends typeof BaseModel, K extends Extract<ModelColumns<InstanceType<T>>, keyof InstanceType<T>>>(this: T, key: K, where?: Partial<InstanceType<T>>): Promise<InstanceType<T>[K]>;
    static pluck<T extends typeof BaseModel>(this: T, key: ModelColumns<InstanceType<T>>, where?: Partial<InstanceType<T>>): Promise<any>;
    /**
     * Find many values in database but returns only the
     * values of selected column directly.
     */
    static pluckMany<T extends typeof BaseModel, K extends Extract<ModelColumns<InstanceType<T>>, keyof InstanceType<T>>>(this: T, key: K, where?: Partial<InstanceType<T>>): Promise<InstanceType<T>[K][]>;
    static pluckMany<T extends typeof BaseModel>(this: T, key: ModelColumns<InstanceType<T>>, where?: Partial<InstanceType<T>>): Promise<any[]>;
    /**
     * Find a value in database.
     */
    static find<T extends typeof BaseModel>(this: T, where?: Partial<InstanceType<T>>): Promise<InstanceType<T>>;
    /**
     * Find a value in database.
     */
    static exists<T extends typeof BaseModel>(this: T, where?: Partial<InstanceType<T>>): Promise<boolean>;
    /**
     * Find a value in database or throw exception if undefined.
     */
    static findOrFail<T extends typeof BaseModel>(this: T, where?: Partial<InstanceType<T>>): Promise<InstanceType<T>>;
    /**
     * Find a value in database or create a new one if it doesn't exist.
     */
    static findOrCreate<T extends typeof BaseModel>(this: T, where: Partial<InstanceType<T>>, data: Partial<InstanceType<T>>): Promise<InstanceType<T>>;
    /**
     * Return a single data or, if no results are found,
     * execute the given closure.
     */
    static findOr<T extends typeof BaseModel>(this: T, where: Partial<InstanceType<T>>, closure: () => any | Promise<any>): Promise<InstanceType<T> | any>;
    /**
     * Find many values in database.
     */
    static findMany<T extends typeof BaseModel>(this: T, where?: Partial<InstanceType<T>>): Promise<InstanceType<T>[]>;
    /**
     * Find many values in database and return paginated.
     */
    static paginate<T extends typeof BaseModel>(this: T, options?: PaginationOptions, where?: Partial<InstanceType<T>>): Promise<PaginatedResponse<InstanceType<T>>>;
    /**
     * Find many values in database and return
     * as a collection instance.
     */
    static collection<T extends typeof BaseModel>(this: T, where?: Partial<InstanceType<T>>): Promise<Collection<InstanceType<T>>>;
    /**
     * Create a value in database.
     */
    static create<T extends typeof BaseModel>(this: T, data?: Partial<InstanceType<T>>, cleanPersist?: boolean): Promise<InstanceType<T>>;
    /**
     * Create many values in database.
     */
    static createMany<T extends typeof BaseModel>(this: T, data: Partial<InstanceType<T>>[], cleanPersist?: boolean): Promise<InstanceType<T>[]>;
    /**
     * Create or update a value in database.
     */
    static createOrUpdate<T extends typeof BaseModel>(this: T, where: Partial<InstanceType<T>>, data: Partial<InstanceType<T>>, cleanPersist?: boolean): Promise<InstanceType<T>>;
    /**
     * Update a value in database.
     */
    static update<T extends typeof BaseModel>(this: T, where: Partial<InstanceType<T>>, data: Partial<InstanceType<T>>, cleanPersist?: boolean): Promise<InstanceType<T> | InstanceType<T>[]>;
    /**
     * Restore a soft deleted value from database.
     */
    static restore<T extends typeof BaseModel>(this: T, where: Partial<InstanceType<T>>, data: Partial<InstanceType<T>>): Promise<InstanceType<T> | InstanceType<T>[]>;
    /**
     * Delete or soft delete a value in database.
     */
    static delete<T extends typeof BaseModel>(this: T, where: Partial<InstanceType<T>>, force?: boolean): Promise<void>;
    /**
     * The original model values when it was fetched
     * from database. If is undefined, means that model
     * is a fresh instance and is not available in database
     * yet.
     */
    private [ORIGINAL_SYMBOL]?;
    /**
     * Set the original model values by deep copying
     * the model state.
     */
    setOriginal(): this;
    /**
     * Return a Json object from the actual subclass instance.
     */
    toJSON(options?: {
        withHidden?: boolean;
    }): Record<string, any>;
    load(relation: string): Promise<any>;
    load<K extends ModelRelations<this>>(relation: K, closure?: (query: ModelQueryBuilder<Extract<this[K] extends BaseModel[] ? this[K][0] : this[K], BaseModel>>) => any): Promise<this[K]>;
    loadOnly(relation: string): Promise<any>;
    loadOnly<K extends ModelRelations<this>>(relation: K, closure?: (query: ModelQueryBuilder<Extract<this[K] extends BaseModel[] ? this[K][0] : this[K], BaseModel>>) => any): Promise<this[K]>;
    /**
     * Validate if model is persisted in database
     * or if it's a fresh instance.
     */
    isPersisted(): boolean;
    /**
     * Get values only that are different from
     * the original symbol to avoid updating
     * data that was not changed.
     */
    dirty(): this | Record<string, any>;
    /**
     * Validate if model has been changed from
     * it initial state when it was retrieved from
     * database.
     */
    isDirty(): boolean;
    /**
     * Save the changes done in the model in database.
     */
    save(cleanPersist?: boolean): Promise<this>;
    /**
     * Create a new instance of the model from retrieving
     * again the data from database. The existing
     * model instance WILL NOT BE affected.
     */
    fresh(): Promise<any>;
    /**
     * Refresh the model instance data retrieving
     * model data using the main primary key. The
     * existing model instance WILL BE affected.
     */
    refresh(): Promise<void>;
    /**
     * Verify if model is soft deleted.
     */
    isTrashed(): boolean;
    /**
     * Delete or soft delete your model from database.
     */
    delete(force?: boolean): Promise<void>;
    /**
     * Restore a soft deleted model from database.
     */
    restore(): Promise<this>;
}
