import { Column } from '../orm/column.js';
import { ExtractTableName, FMTable, InferSchemaOutputFromFMTable, ValidExpandTarget } from '../orm/table.js';
import { FMODataLayer } from '../services.js';
import { ConditionallyWithODataAnnotations, ConditionallyWithSpecialColumns, ExecutableBuilder, ExecuteMethodOptions, ExecuteOptions, NormalizeIncludeSpecialColumns, Result } from '../types.js';
import { ExpandedRelations } from './builders/index.js';
import { RecordLocator } from './builders/mutation-helpers.js';
import { ResolveExpandedRelations, SystemColumnsFromOption, SystemColumnsOption } from './query/types.js';
import { QueryBuilder } from './query-builder.js';
/**
 * Extract the value type from a Column.
 * This uses the phantom type stored in Column to get the actual value type.
 */
type ExtractColumnType<C> = C extends Column<infer T, any> ? T : never;
/**
 * Map a select object to its return type.
 * For each key in the select object, extract the type from the corresponding Column.
 */
type MapSelectToReturnType<TSelect extends Record<string, Column<any, any, any, any>>, _TSchema extends Record<string, any>> = {
    [K in keyof TSelect]: ExtractColumnType<TSelect[K]>;
};
export type RecordReturnType<Schema extends Record<string, any>, IsSingleField extends boolean, FieldColumn extends Column<any, any, any, any> | undefined, Selected extends keyof Schema | Record<string, Column<any, any, ExtractTableName<FMTable<any, any>>>>, Expands extends ExpandedRelations, SystemCols extends SystemColumnsOption | undefined = undefined> = IsSingleField extends true ? FieldColumn extends Column<infer TOutput, any, any, any> ? TOutput : never : [
    Selected
] extends [Record<string, Column<any, any, any, any>>] ? MapSelectToReturnType<Selected, Schema> & ResolveExpandedRelations<Expands> & SystemColumnsFromOption<SystemCols> : [
    Selected
] extends [keyof Schema] ? Pick<Schema, Selected> & ResolveExpandedRelations<Expands> & SystemColumnsFromOption<SystemCols> : never;
type RecordBuilderHasSelect<Occ extends FMTable<any, any>, IsSingleField extends boolean, Selected> = IsSingleField extends true ? false : Selected extends Record<string, Column<any, any, any>> ? true : Selected extends keyof InferSchemaOutputFromFMTable<NonNullable<Occ>> ? false : true;
type ExecutableRecordBuilderReturn<Occ extends FMTable<any, any>, IsSingleField extends boolean, FieldColumn extends Column<any, any, any, any> | undefined, Selected extends keyof InferSchemaOutputFromFMTable<NonNullable<Occ>> | Record<string, Column<any, any, ExtractTableName<NonNullable<Occ>>>>, Expands extends ExpandedRelations, SystemCols extends SystemColumnsOption | undefined> = ConditionallyWithODataAnnotations<ConditionallyWithSpecialColumns<RecordReturnType<InferSchemaOutputFromFMTable<NonNullable<Occ>>, IsSingleField, FieldColumn, Selected, Expands, SystemCols>, true, RecordBuilderHasSelect<Occ, IsSingleField, Selected>>, true> | ConditionallyWithODataAnnotations<ConditionallyWithSpecialColumns<RecordReturnType<InferSchemaOutputFromFMTable<NonNullable<Occ>>, IsSingleField, FieldColumn, Selected, Expands, SystemCols>, true, RecordBuilderHasSelect<Occ, IsSingleField, Selected>>, false> | ConditionallyWithODataAnnotations<ConditionallyWithSpecialColumns<RecordReturnType<InferSchemaOutputFromFMTable<NonNullable<Occ>>, IsSingleField, FieldColumn, Selected, Expands, SystemCols>, false, RecordBuilderHasSelect<Occ, IsSingleField, Selected>>, true> | ConditionallyWithODataAnnotations<ConditionallyWithSpecialColumns<RecordReturnType<InferSchemaOutputFromFMTable<NonNullable<Occ>>, IsSingleField, FieldColumn, Selected, Expands, SystemCols>, false, RecordBuilderHasSelect<Occ, IsSingleField, Selected>>, false>;
export declare class RecordBuilder<Occ extends FMTable<any, any> = FMTable<any, any>, IsSingleField extends boolean = false, FieldColumn extends Column<any, any, any, any> | undefined = undefined, Selected extends keyof InferSchemaOutputFromFMTable<NonNullable<Occ>> | Record<string, Column<any, any, ExtractTableName<NonNullable<Occ>>>> = keyof InferSchemaOutputFromFMTable<NonNullable<Occ>>, Expands extends ExpandedRelations = {}, DatabaseIncludeSpecialColumns extends boolean = false, SystemCols extends SystemColumnsOption | undefined = undefined> implements ExecutableBuilder<ExecutableRecordBuilderReturn<Occ, IsSingleField, FieldColumn, Selected, Expands, SystemCols>> {
    private readonly table;
    private readonly recordLocator;
    private readonly operation?;
    private readonly operationParam?;
    private readonly operationColumn?;
    private readonly isNavigateFromEntitySet?;
    private readonly navigateRelation?;
    private readonly navigateRelationEntityId?;
    private readonly navigateSourceTableName?;
    private readonly navigateSourceTableEntityId?;
    private readState;
    private readonly layer;
    private readonly config;
    private readonly logger;
    private get selectedFields();
    private set selectedFields(value);
    private get expandConfigs();
    private set expandConfigs(value);
    private get fieldMapping();
    private set fieldMapping(value);
    private get systemColumns();
    private set systemColumns(value);
    constructor(config: {
        occurrence: Occ;
        layer: FMODataLayer;
        recordLocator: RecordLocator;
    });
    /**
     * Helper to merge database-level useEntityIds and includeSpecialColumns with per-request options
     */
    private mergeExecuteOptions;
    /**
     * Gets the table ID (FMTID) if using entity IDs, otherwise returns the table name
     * @param useEntityIds - Optional override for entity ID usage
     */
    private getTableId;
    /**
     * Creates a new RecordBuilder with modified configuration.
     * Used by select() to create new instances.
     */
    private cloneWithChanges;
    getSingleField<TColumn extends Column<any, any, ExtractTableName<NonNullable<Occ>>, any>>(column: TColumn): RecordBuilder<Occ, true, TColumn, keyof InferSchemaOutputFromFMTable<NonNullable<Occ>>, {}, DatabaseIncludeSpecialColumns>;
    /**
     * Select fields using column references, or pass "all" to clear any defaultSelect and fetch all fields.
     * Allows renaming fields by using different keys in the object.
     * Container fields cannot be selected and will cause a type error.
     *
     * @example
     * db.from(contacts).get("uuid").select({
     *   name: contacts.name,
     *   userEmail: contacts.email  // renamed!
     * })
     *
     * @example
     * // Include system columns (ROWID, ROWMODID) when using select()
     * db.from(contacts).get("uuid").select(
     *   { name: contacts.name },
     *   { ROWID: true, ROWMODID: true }
     * )
     *
     * @example
     * // Override defaultSelect to fetch all fields
     * db.from(contacts).get("uuid").select("all")
     *
     * @param fields - Object mapping output keys to column references (container fields excluded), or "all" to select all fields
     * @param systemColumns - Optional object to request system columns (ROWID, ROWMODID)
     * @returns RecordBuilder with updated selected fields
     */
    select(fields: "all"): RecordBuilder<Occ, false, FieldColumn, keyof InferSchemaOutputFromFMTable<NonNullable<Occ>>, Expands, DatabaseIncludeSpecialColumns, undefined>;
    select<TSelect extends Record<string, Column<any, any, ExtractTableName<Occ>, false>>, TSystemCols extends SystemColumnsOption = {}>(fields: TSelect, systemColumns?: TSystemCols): RecordBuilder<Occ, false, FieldColumn, TSelect, Expands, DatabaseIncludeSpecialColumns, TSystemCols>;
    /**
     * Expand a navigation property to include related records.
     * Supports nested select, filter, orderBy, and expand operations.
     *
     * @example
     * ```typescript
     * // Simple expand with FMTable object
     * const contact = await db.from(contacts).get("uuid").expand(users).execute();
     *
     * // Expand with select
     * const contact = await db.from(contacts).get("uuid")
     *   .expand(users, b => b.select({ username: users.username, email: users.email }))
     *   .execute();
     * ```
     */
    expand<TargetTable extends FMTable<any, any>, TSelected extends keyof InferSchemaOutputFromFMTable<TargetTable> | Record<string, Column<any, any, ExtractTableName<TargetTable>>> = keyof InferSchemaOutputFromFMTable<TargetTable>, TNestedExpands extends ExpandedRelations = {}>(targetTable: ValidExpandTarget<Occ, TargetTable>, callback?: (builder: QueryBuilder<TargetTable, keyof InferSchemaOutputFromFMTable<TargetTable>, false, false, {}, false>) => QueryBuilder<TargetTable, TSelected, any, any, TNestedExpands, any, any>): RecordBuilder<Occ, false, FieldColumn, Selected, Expands & {
        [K in ExtractTableName<TargetTable>]: {
            schema: InferSchemaOutputFromFMTable<TargetTable>;
            selected: TSelected;
            nested: TNestedExpands;
        };
    }, DatabaseIncludeSpecialColumns, SystemCols>;
    navigate<TargetTable extends FMTable<any, any>>(targetTable: ValidExpandTarget<Occ, TargetTable>): QueryBuilder<TargetTable, keyof InferSchemaOutputFromFMTable<TargetTable>, false, false, {}, false, DatabaseIncludeSpecialColumns, undefined>;
    /**
     * Builds the complete query string including $select and $expand parameters.
     */
    private buildQueryString;
    private buildRecordResourcePath;
    execute<EO extends ExecuteOptions>(options?: ExecuteMethodOptions<EO>): Promise<Result<ConditionallyWithODataAnnotations<ConditionallyWithSpecialColumns<RecordReturnType<InferSchemaOutputFromFMTable<NonNullable<Occ>>, IsSingleField, FieldColumn, Selected, Expands, SystemCols>, NormalizeIncludeSpecialColumns<EO["includeSpecialColumns"], DatabaseIncludeSpecialColumns>, IsSingleField extends true ? false : Selected extends Record<string, Column<any, any, any>> ? true : Selected extends keyof InferSchemaOutputFromFMTable<NonNullable<Occ>> ? false : true>, EO["includeODataAnnotations"] extends true ? true : false>>>;
    getRequestConfig(): {
        method: string;
        url: string;
        body?: any;
    };
    /**
     * Returns the query string for this record builder (for testing purposes).
     */
    getQueryString(options?: {
        useEntityIds?: boolean;
    }): string;
    toRequest(baseUrl: string, options?: ExecuteOptions): Request;
    processResponse(response: Response, options?: ExecuteOptions): Promise<Result<RecordReturnType<InferSchemaOutputFromFMTable<NonNullable<Occ>>, IsSingleField, FieldColumn, Selected, Expands, SystemCols>>>;
}
export {};
