import { ReactNode } from 'react';
import { ColumnDef, ColumnTypeConfig, TextEditConfig, NumberEditConfig, SelectEditConfig, SelectAsyncEditConfig, MultiselectEditConfig, MultiselectAsyncEditConfig, BooleanEditConfig, TableRow, ColumnHeaderConfig } from './types';
import { MultiSelectMenuOption } from '../MultiSelectMenu';
/**
 * Base column configuration shared by all column types
 */
type BaseColumnConfig<T, K extends keyof T> = ColumnHeaderConfig & {
    /**
     * The cleaned-up header configuration.
     */
    header?: ColumnDef<T>["header"];
    /**
     * The label of the header.
     * @deprecated Use `header.label` instead.
     */
    headerLabel?: string;
    /**
     * The alignment of the header.
     * When using `type`, this is set automatically but can be overridden.
     */
    align?: "start" | "center" | "end";
    /**
     * Columns of a group column (for grouped columns)
     */
    columns?: ColumnDef<T>[];
    /**
     * Custom content to display when a cell value is empty (null, undefined, or empty string).
     * Overrides the default em dash. When set on both the column and the DataTable,
     * the column-level value takes precedence.
     */
    emptyCellContent?: ReactNode;
    /**
     * The content of the footer cell. An array will display multiple footer rows
     */
    footerContent?: ReactNode | ReactNode[];
    /**
     * The maximum width of the column, in pixels. Caps automatic growth when
     * the table has extra horizontal space available.
     */
    maxWidth?: number;
    /**
     * The minimum width of the column, in pixels. Used as the floor for manual
     * resize — users can drag a column down to but not below this value. Also
     * serves as the fallback auto-sizing floor when `defaultWidth` is not set.
     */
    minWidth?: number;
    /**
     * The preferred starting width of the column, in pixels. Used as the basis
     * for automatic growing/shrinking: the column renders at this width by
     * default, grows toward `maxWidth` when the table has spare horizontal
     * space, and never auto-shrinks below it — the table scrolls horizontally
     * instead.
     *
     * Manual resize via the column's resize handle is still bounded by
     * `minWidth`/`maxWidth`, so users can drag a column below `defaultWidth`
     * down to `minWidth`.
     *
     * Falls back to `minWidth` when not specified.
     */
    defaultWidth?: number;
    /**
     * The pinning location of the column
     */
    pinned?: "left" | "right";
    /**
     * Whether the column is resizable
     */
    resizable?: boolean;
    /**
     * The function to customize how the cell content is rendered.
     * When using `type`, a default renderer is provided but can be overridden.
     */
    renderCell?: (value: T[K], { row, depth }: {
        row?: TableRow<T>;
        depth?: number;
    }) => ReactNode;
    /**
     * Whether the column is sortable, or a function to customize the sorting logic
     */
    sortable?: boolean | ((valueA: T[K], valueB: T[K]) => number);
    /**
     * The column type for automatic display configuration.
     * Sets default `renderCell` (formatter) and `align` based on the data type.
     */
    type?: ColumnTypeConfig;
};
/**
 * Configuration for read-only columns (no editing)
 */
type ReadOnlyColumnConfig<T, K extends keyof T> = BaseColumnConfig<T, K> & {
    editConfig?: undefined;
};
/**
 * Configuration for text editable columns using editConfig.
 * Valid when T[K] is a string.
 */
type TextEditConfigColumnConfig<T, K extends keyof T> = NonNullable<T[K]> extends string ? BaseColumnConfig<T, K> & {
    editConfig: TextEditConfig<T, K>;
} : never;
/**
 * Configuration for number editable columns using editConfig.
 * Valid when T[K] is a number type.
 */
type NumberEditConfigColumnConfig<T, K extends keyof T> = NonNullable<T[K]> extends number ? BaseColumnConfig<T, K> & {
    editConfig: NumberEditConfig<T, K>;
} : never;
/**
 * Configuration for select editable columns using editConfig
 */
type SelectEditConfigColumnConfig<T, K extends keyof T> = BaseColumnConfig<T, K> & {
    editConfig: SelectEditConfig<T, K>;
};
/**
 * Configuration for async select editable columns using editConfig
 */
type SelectAsyncEditConfigColumnConfig<T, K extends keyof T> = BaseColumnConfig<T, K> & {
    editConfig: SelectAsyncEditConfig<T>;
};
type CellArrayItem = object | string | number | boolean | bigint | symbol | null | undefined;
type CellArrayValue = readonly CellArrayItem[];
/**
 * Configuration for multiselect editable columns using editConfig
 * Only valid when T[K] is an array type
 */
type MultiselectEditConfigColumnConfig<T, K extends keyof T> = NonNullable<T[K]> extends CellArrayValue ? BaseColumnConfig<T, K> & {
    editConfig: MultiselectEditConfig<T, K>;
} : never;
/**
 * Configuration for async multiselect editable columns using editConfig.
 * Only valid when T[K] is MultiSelectMenuOption[] — full option objects,
 * not a plain primitive array like string[].
 */
type MultiselectAsyncEditConfigColumnConfig<T, K extends keyof T> = NonNullable<T[K]> extends MultiSelectMenuOption[] ? BaseColumnConfig<T, K> & {
    editConfig: MultiselectAsyncEditConfig<T>;
} : never;
/**
 * Configuration for boolean editable columns using editConfig.
 * Valid when T[K] is a boolean type.
 */
type BooleanEditConfigColumnConfig<T, K extends keyof T> = NonNullable<T[K]> extends boolean ? BaseColumnConfig<T, K> & {
    editConfig: BooleanEditConfig<T, K>;
} : never;
/**
 * Full column configuration type - union of all possible configurations.
 * TypeScript will enforce that the editConfig matches the value type constraints.
 */
type ColumnConfig<T, K extends keyof T> = ReadOnlyColumnConfig<T, K> | TextEditConfigColumnConfig<T, K> | NumberEditConfigColumnConfig<T, K> | SelectEditConfigColumnConfig<T, K> | SelectAsyncEditConfigColumnConfig<T, K> | MultiselectEditConfigColumnConfig<T, K> | MultiselectAsyncEditConfigColumnConfig<T, K> | BooleanEditConfigColumnConfig<T, K>;
/**
 * Factory function to create column helper function for defining Table columns.
 *
 * This helper provides type safety by enforcing that:
 * - `type` sets display defaults (formatter and alignment) for the column
 * - `editConfig` enables cell editing with proper type constraints
 * - `editConfig.mode: "text"` can only be used with string columns
 * - `editConfig.mode: "boolean"` can only be used with boolean columns
 * - `editConfig.mode: "number"` can only be used with number columns
 * - `editConfig.mode: "multiselect"` can only be used with array columns
 * - `editConfig.mode: "select"` options values must match the column's value type
 * - `editConfig.onChange` callback receives the correct value type for the column
 *
 * @template T - The type of the row data
 * @returns A function that creates type-safe column definitions
 *
 * @example
 * ```ts
 * type Data = { name: string; amount: number; tags: string[] };
 * const createColumn = createColumnHelper<Data>();
 *
 * // Display-only column with type defaults
 * createColumn("amount", { header: { label: "Amount" }, type: "currency" });
 *
 * // Editable column with editConfig
 * createColumn("name", {
 *   header: { label: "Name" },
 *   type: "text",
 *   editConfig: { mode: "text", onChange: (value, rowId) => save(value, rowId) }
 * });
 *
 * // Number editing
 * createColumn("amount", {
 *   header: { label: "Amount" },
 *   editConfig: {
 *     mode: "number",
 *     minValue: 0,
 *     maxValue: 10000,
 *     step: 0.01,
 *     onChange: (value, rowId) => save(value, rowId)
 *   }
 * });
 *
 * // Select editing
 * createColumn("status", {
 *   header: { label: "Status" },
 *   editConfig: {
 *     mode: "select",
 *     options: [{ id: "active", label: "Active" }],
 *     onChange: (option, rowId) => save(option?.id, rowId)
 *   }
 * });
 *
 * // Multiselect editing with array column
 * createColumn("tags", {
 *   header: { label: "Tags" },
 *   editConfig: {
 *     mode: "multiselect",
 *     options: [{ id: "urgent", label: "Urgent" }],
 *     onChange: (options, rowId) => save(options.map(o => o.id), rowId)
 *   }
 * });
 * ```
 */
export declare function createColumnHelper<T>(): <K extends keyof T>(id: K | {
    group: string;
}, column: ColumnConfig<T, K>) => ColumnDef<T>;
export {};
