import { type EntityMetadata, type EntityProperty } from '@mikro-orm/core';
import {
  type CommonTableExpressionNameNode,
  type DeleteQueryNode,
  type IdentifierNode,
  type InsertQueryNode,
  type JoinNode,
  type MergeQueryNode,
  type QueryId,
  type SelectQueryNode,
  type UpdateQueryNode,
  type WithNode,
  ColumnNode,
  OperationNodeTransformer,
  TableNode,
} from 'kysely';
import type { MikroKyselyPluginOptions } from './index.js';
import type { SqlEntityManager } from '../SqlEntityManager.js';
export declare class MikroTransformer extends OperationNodeTransformer {
  #private;
  constructor(em: SqlEntityManager, options?: MikroKyselyPluginOptions);
  reset(): void;
  getOutputEntityMap(): Map<string, EntityMetadata>;
  /** @internal */
  getContextStack(): Map<string, EntityMetadata | undefined>[];
  /** @internal */
  getSubqueryAliasMap(): Map<string, EntityMetadata | undefined>;
  transformSelectQuery(node: SelectQueryNode, queryId: QueryId): SelectQueryNode;
  transformInsertQuery(node: InsertQueryNode, queryId?: QueryId): InsertQueryNode;
  transformUpdateQuery(node: UpdateQueryNode, queryId?: QueryId): UpdateQueryNode;
  transformDeleteQuery(node: DeleteQueryNode, queryId?: QueryId): DeleteQueryNode;
  transformMergeQuery(node: MergeQueryNode, queryId?: QueryId): MergeQueryNode;
  transformIdentifier(node: IdentifierNode, queryId: QueryId): IdentifierNode;
  /**
   * Find owner entity metadata for the current identifier in the context stack.
   * Supports both aliased and non-aliased table references.
   * Searches up the context stack to support correlated subqueries.
   * Also checks subquery/CTE aliases to resolve to their source tables.
   */
  findOwnerEntityInContext(): EntityMetadata | undefined;
  processOnCreateHooks(node: InsertQueryNode, meta: EntityMetadata): InsertQueryNode;
  processOnUpdateHooks(node: UpdateQueryNode, meta: EntityMetadata): UpdateQueryNode;
  processInsertValues(node: InsertQueryNode, meta: EntityMetadata): InsertQueryNode;
  processUpdateValues(node: UpdateQueryNode, meta: EntityMetadata): UpdateQueryNode;
  mapColumnsToProperties(columns: readonly ColumnNode[], meta: EntityMetadata): (EntityProperty | undefined)[];
  normalizeColumnName(identifier: IdentifierNode): string;
  findProperty(meta: EntityMetadata | undefined, columnName?: string): EntityProperty | undefined;
  shouldConvertValues(): boolean;
  prepareInputValue(prop: EntityProperty | undefined, value: unknown, enabled: boolean): unknown;
  /**
   * Look up a table name/alias in the context stack.
   * Searches from current scope (top of stack) to parent scopes (bottom).
   * This supports correlated subqueries and references to outer query tables.
   */
  lookupInContextStack(tableNameOrAlias: string): EntityMetadata | undefined;
  /**
   * Process WITH node (CTE definitions)
   */
  processWithNode(withNode: WithNode, context: Map<string, EntityMetadata | undefined>): void;
  /**
   * Extract CTE name from CommonTableExpressionNameNode
   */
  getCTEName(nameNode: CommonTableExpressionNameNode): string | undefined;
  /**
   * Process a FROM item (can be TableNode or AliasNode)
   */
  processFromItem(
    from: any, // OperationNode type - can be TableNode, AliasNode, or SelectQueryNode
    context: Map<string, EntityMetadata | undefined>,
  ): void;
  /**
   * Process a JOIN node
   */
  processJoinNode(join: JoinNode, context: Map<string, EntityMetadata | undefined>): void;
  /**
   * Extract the primary source table from a SELECT query
   * This helps resolve columns from subqueries to their original entity tables
   */
  extractSourceTableFromSelectQuery(selectQuery: SelectQueryNode): EntityMetadata | undefined;
  /**
   * Extract alias name from an alias node
   */
  extractAliasName(alias: any): string | undefined;
  /**
   * Extract table name from a TableNode
   */
  getTableName(node: TableNode | undefined): string | undefined;
  /**
   * Find entity metadata by table name or entity name
   */
  findEntityMetadata(name: string): EntityMetadata | undefined;
  /**
   * Transform result rows by mapping database column names to property names
   * This is called for SELECT queries when columnNamingStrategy is 'property'
   */
  transformResult(
    rows: Record<string, any>[] | undefined,
    entityMap: Map<string, EntityMetadata>,
  ): Record<string, any>[] | undefined;
  buildGlobalFieldMap(entityMap: Map<string, EntityMetadata>): Record<string, EntityProperty>;
  buildGlobalRelationFieldMap(entityMap: Map<string, EntityMetadata>): Record<string, string>;
  /**
   * Build a mapping from database field names to property objects
   * Format: { 'field_name': EntityProperty }
   */
  buildFieldToPropertyMap(meta: EntityMetadata, alias?: string): Record<string, EntityProperty>;
  /**
   * Build a mapping for relation fields
   * For ManyToOne relations, we need to map from the foreign key field to the relation property
   * Format: { 'foreign_key_field': 'relationPropertyName' }
   */
  buildRelationFieldMap(meta: EntityMetadata, alias?: string): Record<string, string>;
  /**
   * Transform a single row by mapping column names to property names
   */
  transformRow(
    row: Record<string, any>,
    fieldToPropertyMap: Record<string, EntityProperty>,
    relationFieldMap: Record<string, string>,
  ): Record<string, any>;
  prepareOutputValue(prop: EntityProperty | undefined, value: unknown): unknown;
}
