import {
  type Dictionary,
  type EntityData,
  type EntityKey,
  type EntityMetadata,
  type EntityName,
  type EntityProperty,
  type FilterQuery,
  type FlatQueryOrderMap,
  type FormulaTable,
  LockMode,
  type QueryOrderMap,
  Raw,
  type RawQueryFragment,
  type RawQueryFragmentSymbol,
} from '@mikro-orm/core';
import { JoinType, QueryType } from './enums.js';
import type { InternalField, JoinOptions } from '../typings.js';
import type { AbstractSqlDriver } from '../AbstractSqlDriver.js';
import type { NativeQueryBuilder } from './NativeQueryBuilder.js';
/**
 * @internal
 */
export declare class QueryBuilderHelper {
  #private;
  constructor(
    entityName: EntityName,
    alias: string,
    aliasMap: Dictionary<Alias<any>>,
    subQueries: Dictionary<string>,
    driver: AbstractSqlDriver,
    tptAliasMap?: Dictionary<string>,
  );
  /**
   * For TPT inheritance, finds the correct alias for a property based on which entity owns it.
   * Returns the main alias if not a TPT property or if the property belongs to the main entity.
   */
  getTPTAliasForProperty(propName: string, defaultAlias: string): string;
  mapper(field: string | Raw | RawQueryFragmentSymbol, type?: QueryType): string;
  mapper(
    field: string | Raw | RawQueryFragmentSymbol,
    type?: QueryType,
    value?: any,
    alias?: string | null,
    schema?: string,
  ): string;
  processData(data: Dictionary, convertCustomTypes: boolean, multi?: boolean): any;
  joinOneToReference(
    prop: EntityProperty,
    ownerAlias: string,
    alias: string,
    type: JoinType,
    cond?: Dictionary,
    schema?: string,
  ): JoinOptions;
  joinManyToOneReference(
    prop: EntityProperty,
    ownerAlias: string,
    alias: string,
    type: JoinType,
    cond?: Dictionary,
    schema?: string,
  ): JoinOptions;
  joinManyToManyReference(
    prop: EntityProperty,
    ownerAlias: string,
    alias: string,
    pivotAlias: string,
    type: JoinType,
    cond: Dictionary,
    path: string,
    schema?: string,
  ): Dictionary<JoinOptions>;
  processJoins(qb: NativeQueryBuilder, joins: Dictionary<JoinOptions>, schema?: string, schemaOverride?: string): void;
  createJoinExpression(
    join: JoinOptions,
    joins: Dictionary<JoinOptions>,
    schema?: string,
    schemaOverride?: string,
  ): {
    sql: string;
    params: unknown[];
  };
  mapJoinColumns(type: QueryType, join: JoinOptions): (string | Raw)[];
  isOneToOneInverse(field: string, meta?: EntityMetadata): boolean;
  getTableName(entityName: EntityName): string;
  /**
   * Checks whether the RE can be rewritten to simple LIKE query
   */
  isSimpleRegExp(re: any): re is RegExp;
  getRegExpParam(re: RegExp): string;
  appendOnConflictClause<T>(type: QueryType, onConflict: OnConflictClause<T>[], qb: NativeQueryBuilder): void;
  appendQueryCondition(
    type: QueryType,
    cond: any,
    qb: NativeQueryBuilder,
    operator?: '$and' | '$or',
    method?: 'where' | 'having',
  ): void;
  _appendQueryCondition(
    type: QueryType,
    cond: any,
    operator?: '$and' | '$or',
  ): {
    sql: string;
    params: unknown[];
  };
  private append;
  private appendQuerySubCondition;
  private processObjectSubCondition;
  private getValueReplacement;
  private getOperatorReplacement;
  validateQueryOrder<T>(orderBy: QueryOrderMap<T>): void;
  getQueryOrder(
    type: QueryType,
    orderBy: FlatQueryOrderMap | FlatQueryOrderMap[],
    populate: Dictionary<string>,
    collation?: string,
  ): string[];
  getQueryOrderFromObject(
    type: QueryType,
    orderBy: FlatQueryOrderMap,
    populate: Dictionary<string>,
    collation?: string,
  ): string[];
  splitField<T>(field: EntityKey<T>, greedyAlias?: boolean): [string, EntityKey<T>, string | undefined];
  getLockSQL(
    qb: NativeQueryBuilder,
    lockMode: LockMode,
    lockTables?: string[],
    joinsMap?: Dictionary<JoinOptions>,
  ): void;
  updateVersionProperty(qb: NativeQueryBuilder, data: Dictionary): void;
  private prefix;
  private appendGroupCondition;
  private isPrefixed;
  private fieldName;
  getProperty(field: string, alias?: string): EntityProperty | undefined;
  isTableNameAliasRequired(type: QueryType): boolean;
  private processEmbeddedArrayCondition;
  private buildJsonArrayExists;
  private resolveEmbeddedProp;
  private buildEmbeddedArrayOperatorCondition;
  private processJsonElemMatch;
  /**
   * Shared logic for building WHERE conditions inside JSON array EXISTS subqueries.
   * Used by both embedded array queries (metadata-driven) and $elemMatch (type-inferred).
   */
  private buildArrayElementWhere;
  private inferJsonValueType;
  processOnConflictCondition(cond: FilterQuery<any>, schema?: string): FilterQuery<any>;
  createFormulaTable(alias: string, meta: EntityMetadata, schema?: string): FormulaTable;
}
export interface Alias<T> {
  aliasName: string;
  entityName: EntityName<T>;
  meta: EntityMetadata<T>;
  subQuery?: NativeQueryBuilder | RawQueryFragment;
  rawTableName?: string;
}
export interface OnConflictClause<T> {
  fields: string[] | Raw;
  ignore?: boolean;
  merge?: EntityData<T> | InternalField<T>[];
  where?: FilterQuery<T>;
}
