import { CollectionReference, DocumentData, DocumentReference, DocumentSnapshot, FieldPath, FirestoreDataConverter, Query, QueryDocumentSnapshot, SetOptions, UpdateData, WhereFilterOp, WriteResult } from "firebase-admin/firestore";
import "reflect-metadata";
import { ZodSchema } from "zod";
import { BaseModelConstructor, BaseModelInterface, FindAllResult, FindOptions, RelationMetadata } from "./types";
export declare abstract class BaseModel implements BaseModelInterface {
    id?: string;
    private __parent?;
    private __docRef?;
    private static _builtSchema?;
    static get schema(): ZodSchema<any>;
    protected _populatedRelations: {
        [key: string]: BaseModel | BaseModel[] | null;
    };
    constructor(data: Record<string, any>, idOrParent?: string | BaseModel);
    get docRef(): DocumentReference;
    get collectionRef(): CollectionReference;
    static _getCollectionName(): string;
    static _getRelationMetadata(): RelationMetadata[];
    static getCollectionRef<T extends typeof BaseModel>(this: BaseModelConstructor<T>): CollectionReference<T>;
    static _getFirestoreConverter<T extends BaseModel>(this: BaseModelConstructor): FirestoreDataConverter<T>;
    /**
     * Get a typed CollectionReference for a named subcollection on this document.
     */
    subcollection<Sub extends BaseModel>(this: this, prop: keyof this, queryFn?: (ref: CollectionReference<Sub>) => Query<Sub>): Promise<Sub[]>;
    static _fromFirestore<T extends typeof BaseModel>(this: T & BaseModelConstructor, snapshot: DocumentSnapshot | QueryDocumentSnapshot): InstanceType<T> | null;
    static findById<T extends typeof BaseModel>(this: T & BaseModelConstructor, id: string, options?: FindOptions): Promise<InstanceType<T> | null>;
    static findAll<T extends typeof BaseModel>(this: T & BaseModelConstructor, options?: FindOptions): Promise<FindAllResult<InstanceType<T>>>;
    static findWhere<T extends typeof BaseModel, K extends keyof T>(this: T & BaseModelConstructor, field: K | string | FieldPath, // Allow string or FieldPath
    operator: WhereFilterOp, value: any, options?: FindOptions): Promise<InstanceType<T>[]>;
    static findOne<T extends typeof BaseModel>(this: T & BaseModelConstructor, queryFn: (ref: CollectionReference<T>) => Query<T>, options?: Pick<FindOptions, "populate">): Promise<InstanceType<T> | null>;
    protected _getConstructor<T extends typeof BaseModel>(): BaseModelConstructor<T>;
    protected _getCollectionRef<T extends typeof BaseModel>(): CollectionReference<T>;
    protected _getDocRef(): DocumentReference<DocumentData>;
    protected _toFirestore(serializing?: boolean): DocumentData;
    populate<K extends keyof this>(fieldNames: K | K[] | boolean): Promise<void>;
    validate(dataToValidate?: DocumentData): void;
    /**
     * Saves (creates or overwrites) the document in Firestore.
     * If executed within an active transaction or batch context (started via `runInTransaction` or `runInBatch`),
     * the operation will be added to that context.
     *
     * @param options Options for the Firestore `set` operation (e.g., `{ merge: true }`).
     * @returns A Promise resolving with the `WriteResult` for direct operations, or `undefined` if executed within a transaction/batch context.
     * @throws {ValidationError} If validation against the static schema fails.
     */
    save(options?: SetOptions): Promise<WriteResult | undefined>;
    /**
     * Updates specific fields of the document in Firestore. Requires the instance to have an ID.
     * If executed within an active transaction or batch context (started via `runInTransaction` or `runInBatch`),
     * the operation will be added to that context.
     *
     * @param updateData Object containing the fields to update. Can include `FieldValue`s.
     * @returns A Promise resolving with the `WriteResult` for direct operations, or `undefined` if executed within a transaction/batch context.
     * @throws {ValidationError} If validation against the static schema fails for the updated fields (if implemented).
     * @throws {Error} If the instance does not have an `id`.
     */
    update(updateData: UpdateData<this>): Promise<WriteResult | undefined>;
    /**
     * Deletes the document from Firestore. Requires the instance to have an ID.
     * If executed within an active transaction or batch context (started via `runInTransaction` or `runInBatch`),
     * the operation will be added to that context.
     *
     * @returns A Promise resolving with the `WriteResult` for direct operations, or `undefined` if executed within a transaction/batch context.
     * @throws {Error} If the instance does not have an `id`.
     */
    delete(): Promise<WriteResult | undefined>;
    reload<T extends typeof BaseModel>(this: any, options?: Pick<FindOptions<T>, "populate">): Promise<T>;
    /**
     * Express/etc will call toJSON() under the hood,
     * and the payload will only contain the real fields.
     */
    toJSON(): Record<string, any>;
    private _updateLocalState;
    beforeSave(options?: SetOptions): Promise<void>;
    afterSave(result: WriteResult, options?: SetOptions): Promise<void>;
    beforeUpdate(data: UpdateData<this>): Promise<void>;
    afterUpdate(result: WriteResult, data: UpdateData<this>): Promise<void>;
    beforeDelete(): Promise<void>;
    afterDelete(result: WriteResult, originalId: string): Promise<void>;
    afterLoad(snapshot: DocumentSnapshot | QueryDocumentSnapshot): Promise<void>;
}
//# sourceMappingURL=base-model.d.ts.map