import { AnyMySqlColumn } from "../columns/common.cjs";
import { QueryBuilder } from "./query-builder.cjs";
import { SelectedFieldsOrdered } from "./select.types.cjs";
import { MySqlUpdateSetSource } from "./update.cjs";
import { entityKind } from "../../entity.cjs";
import { TypedQueryBuilder } from "../../query-builders/query-builder.cjs";
import { CommentInput, Placeholder, Query, SQL, SQLWrapper } from "../../sql/sql.cjs";
import { InferInsertModel, InferModelFromColumns } from "../../table.cjs";
import { Assume, DrizzleTypeError } from "../../utils.cjs";
import { MySqlTable } from "../table.cjs";
import { MySqlDialect } from "../dialect.cjs";
import { AnyMySqlQueryResultHKT, MySqlQueryResultHKT, MySqlQueryResultKind, MySqlSession } from "../session.cjs";

//#region src/mysql-core/query-builders/insert.d.ts
interface MySqlInsertConfig<TTable extends MySqlTable = MySqlTable> {
  table: TTable;
  values: Record<string, unknown>[] | TypedQueryBuilder<MySqlInsertSelection<TTable>> | SQL;
  ignore: boolean;
  onConflict?: SQL;
  returning?: SelectedFieldsOrdered;
  select?: boolean;
  columnList?: string[];
  comment?: SQL;
}
type AnyMySqlInsertConfig = MySqlInsertConfig<MySqlTable>;
type MySqlInsertValue<TTable extends MySqlTable, TColumnsList extends string[] | 'all' = 'all', TModel extends Record<string, any> = InferInsertModel<TTable>> = { [K in keyof TModel as TColumnsList extends 'all' ? K : Extract<K, TColumnsList[number]>]: TModel[K] | SQL | Placeholder } & {};
type MySqlInsertSelection<TTable extends MySqlTable, TColumnsList extends string[] | 'all' = 'all', TModel extends Record<string, unknown> = InferInsertModel<TTable>> = { [K in keyof TModel as TColumnsList extends 'all' ? K : Extract<K, TColumnsList[number]>]: AnyMySqlColumn | SQL | SQL.Aliased | TModel[K] } & {};
type NoDuplicateColumns<T extends readonly unknown[], TSeen = never> = T extends readonly [infer Head, ...infer Tail] ? [Head extends TSeen ? DrizzleTypeError<`Duplicate columns are not allowed in insert selection: "${Head & string}"`> : Head, ...NoDuplicateColumns<Tail, TSeen | Head>] : T;
type ValidateInsertSelectionKey<TTable extends MySqlTable, TSelection extends MySqlInsertSelection<any>, K extends keyof TSelection> = K extends keyof InferInsertModel<TTable> ? TSelection[K] : K extends keyof InferInsertModel<TTable, {
  override: true;
}> ? DrizzleTypeError<`Column "${K & string}" in table "${TTable['_']['name']}" is a generated column - manual value insertion restricted`> : DrizzleTypeError<`Column "${K & string}" does not exist in table "${TTable['_']['name']}"`>;
type NoUnknownKeysInInsertSelection<TTable extends MySqlTable, TSelection extends MySqlInsertSelection<any>, TColumnList extends string[] | 'all' = 'all'> = { [K in keyof TSelection]: TColumnList extends string[] ? K extends TColumnList[number] ? ValidateInsertSelectionKey<TTable, TSelection, K> : DrizzleTypeError<`Column "${K & string}" is not included in the insert column selection`> : ValidateInsertSelectionKey<TTable, TSelection, K> };
interface MySqlInsertBuilderConstructor {
  new (table: MySqlTable, values: MySqlInsertConfig['values'], ignore: boolean, session: MySqlSession, dialect: MySqlDialect, select?: boolean, columnList?: string[]): AnyMySqlInsert;
}
declare class MySqlInsertBuilder<TTable extends MySqlTable, TQueryResult extends MySqlQueryResultHKT, TColumnList extends string[] | 'all' = 'all', TBuilderHKT extends MySqlInsertHKTBase = MySqlInsertHKT> {
  private table;
  private session;
  private dialect;
  private columnList?;
  private builder;
  static readonly [entityKind]: string;
  private shouldIgnore;
  constructor(table: TTable, session: MySqlSession, dialect: MySqlDialect, columnList?: string[] | undefined, builder?: MySqlInsertBuilderConstructor);
  ignore(): this;
  values(value: MySqlInsertValue<TTable, TColumnList>): MySqlInsertKind<TBuilderHKT, TTable, TQueryResult>;
  values(values: MySqlInsertValue<TTable, TColumnList>[]): MySqlInsertKind<TBuilderHKT, TTable, TQueryResult>;
  select<TSelection extends MySqlInsertSelection<TTable, TColumnList>>(selectQuery: (qb: QueryBuilder) => TypedQueryBuilder<NoUnknownKeysInInsertSelection<TTable, TSelection, TColumnList>>): MySqlInsertKind<TBuilderHKT, TTable, TQueryResult>;
  select(selectQuery: (qb: QueryBuilder) => SQL): MySqlInsertKind<TBuilderHKT, TTable, TQueryResult>;
  select(selectQuery: SQL): MySqlInsertKind<TBuilderHKT, TTable, TQueryResult>;
  select<TSelection extends MySqlInsertSelection<TTable, TColumnList>>(selectQuery: TypedQueryBuilder<NoUnknownKeysInInsertSelection<TTable, TSelection, TColumnList>>): MySqlInsertKind<TBuilderHKT, TTable, TQueryResult>;
}
type MySqlInsertWithout<T extends AnyMySqlInsert, TDynamic extends boolean, K extends keyof T & string> = TDynamic extends true ? T : Omit<MySqlInsertKind<T['_']['hkt'], T['_']['table'], T['_']['queryResult'], T['_']['returning'], TDynamic, T['_']['excludedMethods'] | K>, T['_']['excludedMethods'] | K>;
type MySqlInsertDynamic<T extends AnyMySqlInsert> = MySqlInsertKind<T['_']['hkt'], T['_']['table'], T['_']['queryResult'], T['_']['returning'], true, never>;
type MySqlInsertOnDuplicateKeyUpdateConfig<T extends AnyMySqlInsert> = {
  set: MySqlUpdateSetSource<T['_']['table']>;
};
type MySqlInsert<TTable extends MySqlTable = MySqlTable, TQueryResult extends MySqlQueryResultHKT = AnyMySqlQueryResultHKT, TReturning extends Record<string, unknown> | undefined = Record<string, unknown> | undefined> = MySqlInsertBase<MySqlInsertHKT, TTable, TQueryResult, TReturning, true, never>;
type MySqlInsertReturning<T extends AnyMySqlInsert> = T extends any ? MySqlInsertWithout<MySqlInsertKind<T['_']['hkt'], T['_']['table'], T['_']['queryResult'], InferModelFromColumns<GetPrimarySerialOrDefaultKeys<T['_']['table']['_']['columns']>>, T['_']['dynamic'], T['_']['excludedMethods']>, T['_']['dynamic'], '$returningId'> : never;
type AnyMySqlInsert = MySqlInsertBase<any, any, any, any, any, any>;
interface MySqlInsertHKTBase {
  table: unknown;
  queryResult: unknown;
  returning: unknown;
  dynamic: boolean;
  excludedMethods: string;
  _type: unknown;
}
interface MySqlInsertHKT extends MySqlInsertHKTBase {
  _type: MySqlInsertBase<MySqlInsertHKT, Assume<this['table'], MySqlTable>, Assume<this['queryResult'], MySqlQueryResultHKT>, Assume<this['returning'], Record<string, unknown> | undefined>, this['dynamic'], this['excludedMethods']>;
}
type MySqlInsertKind<T extends MySqlInsertHKTBase, TTable extends MySqlTable, TQueryResult extends MySqlQueryResultHKT, TReturning extends Record<string, unknown> | undefined = undefined, TDynamic extends boolean = false, TExcludedMethods extends string = never> = (T & {
  table: TTable;
  queryResult: TQueryResult;
  returning: TReturning;
  dynamic: TDynamic;
  excludedMethods: TExcludedMethods;
})['_type'];
interface MySqlInsertBase<THKT extends MySqlInsertHKTBase, TTable extends MySqlTable, TQueryResult extends MySqlQueryResultHKT, TReturning extends Record<string, unknown> | undefined = undefined, TDynamic extends boolean = false, TExcludedMethods extends string = never> extends SQLWrapper {
  readonly _: {
    readonly dialect: 'mysql';
    readonly hkt: THKT;
    readonly table: TTable;
    readonly queryResult: TQueryResult;
    readonly dynamic: TDynamic;
    readonly excludedMethods: TExcludedMethods;
    readonly returning: TReturning;
    readonly result: TReturning extends undefined ? MySqlQueryResultKind<TQueryResult, never> : TReturning[];
  };
}
type PrimaryKeyKeys<T extends Record<string, AnyMySqlColumn>> = { [K in keyof T]: T[K]['_']['isPrimaryKey'] extends true ? T[K]['_']['isAutoincrement'] extends true ? K : T[K]['_']['hasRuntimeDefault'] extends true ? T[K]['_']['isPrimaryKey'] extends true ? K : never : never : T[K]['_']['hasRuntimeDefault'] extends true ? T[K]['_']['isPrimaryKey'] extends true ? K : never : never }[keyof T];
type GetPrimarySerialOrDefaultKeys<T extends Record<string, AnyMySqlColumn>> = { [K in PrimaryKeyKeys<T>]: T[K] };
declare class MySqlInsertBase<THKT extends MySqlInsertHKTBase, TTable extends MySqlTable, TQueryResult extends MySqlQueryResultHKT, TReturning extends Record<string, unknown> | undefined = undefined, TDynamic extends boolean = false, TExcludedMethods extends string = never> implements SQLWrapper {
  protected session: MySqlSession;
  protected dialect: MySqlDialect;
  static readonly [entityKind]: string;
  protected $table: TTable;
  protected config: MySqlInsertConfig<TTable>;
  constructor(table: TTable, values: MySqlInsertConfig['values'], ignore: boolean, session: MySqlSession, dialect: MySqlDialect, select?: boolean, columnList?: string[]);
  /**
   * Adds an `on duplicate key update` clause to the query.
   *
   * Calling this method will update the row if any unique index conflicts. MySQL will automatically determine the conflict target based on the primary key and unique indexes.
   *
   * See docs: {@link https://orm.drizzle.team/docs/insert#on-duplicate-key-update}
   *
   * @param config The `set` clause
   *
   * @example
   * ```ts
   * await db.insert(cars)
   *   .values({ id: 1, brand: 'BMW'})
   *   .onDuplicateKeyUpdate({ set: { brand: 'Porsche' }});
   * ```
   *
   * While MySQL does not directly support doing nothing on conflict, you can perform a no-op by setting any column's value to itself and achieve the same effect:
   *
   * ```ts
   * import { sql } from 'drizzle-orm';
   *
   * await db.insert(cars)
   *   .values({ id: 1, brand: 'BMW' })
   *   .onDuplicateKeyUpdate({ set: { id: sql`id` } });
   * ```
   */
  onDuplicateKeyUpdate(config: MySqlInsertOnDuplicateKeyUpdateConfig<this>): MySqlInsertWithout<this, TDynamic, 'onDuplicateKeyUpdate'>;
  $returningId(): MySqlInsertReturning<this>;
  /**
   * Attach [sqlcommenter](https://google.github.io/sqlcommenter) comment to a query
   */
  comment(comment: CommentInput): MySqlInsertWithout<this, TDynamic, 'comment'>;
  getSQL(): SQL;
  toSQL(): Query;
  $dynamic(): MySqlInsertDynamic<this>;
}
//#endregion
export { AnyMySqlInsert, AnyMySqlInsertConfig, GetPrimarySerialOrDefaultKeys, MySqlInsert, MySqlInsertBase, MySqlInsertBuilder, MySqlInsertBuilderConstructor, MySqlInsertConfig, MySqlInsertDynamic, MySqlInsertHKT, MySqlInsertHKTBase, MySqlInsertKind, MySqlInsertOnDuplicateKeyUpdateConfig, MySqlInsertReturning, MySqlInsertSelection, MySqlInsertValue, MySqlInsertWithout, NoDuplicateColumns, NoUnknownKeysInInsertSelection, PrimaryKeyKeys, ValidateInsertSelectionKey };
//# sourceMappingURL=insert.d.cts.map