import { ReactNode } from 'react';
import { ColumnDef, ColumnTypeConfig, TextEditConfig, NumberEditConfig, SelectEditConfig, MultiselectEditConfig, BooleanEditConfig, TableRow } from './types';
/**
 * Utility type that extracts the element type from an array type
 */
type ArrayElement<T> = T extends (infer U)[] ? U : never;
/**
 * Base column configuration without editMode-specific or editConfig-specific properties
 */
type BaseColumnConfig<T, K extends keyof T> = {
    /**
     * The label of the header
     */
    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>[];
    /**
     * The content of the footer cell. An array will display multiple footer rows
     */
    footerContent?: ReactNode | ReactNode[];
    /**
     * The maximum width of the column, in pixels
     */
    maxWidth?: number;
    /**
     * The minimum width of the column, in pixels
     */
    minWidth?: 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;
    editMode?: undefined;
    onChange?: never;
    options?: never;
};
/**
 * 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>;
    editMode?: undefined;
    onChange?: undefined;
    options?: undefined;
} : 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>;
    editMode?: undefined;
    onChange?: undefined;
    options?: undefined;
} : never;
/**
 * Configuration for select editable columns using editConfig
 */
type SelectEditConfigColumnConfig<T, K extends keyof T> = BaseColumnConfig<T, K> & {
    editConfig: SelectEditConfig<T, K>;
    editMode?: undefined;
    onChange?: undefined;
    options?: undefined;
};
/**
 * 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 unknown[] ? BaseColumnConfig<T, K> & {
    editConfig: MultiselectEditConfig<T, K>;
    editMode?: undefined;
    onChange?: undefined;
    options?: undefined;
} : 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>;
    editMode?: undefined;
    onChange?: undefined;
    options?: undefined;
} : never;
/**
 * Configuration for text editable columns (legacy).
 * Valid when T[K] is a string.
 * @deprecated Use editConfig instead: `editConfig: { mode: "text", onChange: ... }`
 */
type TextEditableColumnConfig<T, K extends keyof T> = NonNullable<T[K]> extends string ? BaseColumnConfig<T, K> & {
    editConfig?: undefined;
    editMode: "text";
    onChange?: (value: string, rowId: string) => void;
    options?: never;
} : never;
/**
 * Configuration for select editable columns (legacy)
 * @deprecated Use editConfig instead: `editConfig: { mode: "select", options: [...], onChange: ... }`
 */
type SelectEditableColumnConfig<T, K extends keyof T> = BaseColumnConfig<T, K> & {
    editConfig?: undefined;
    editMode: "select";
    onChange?: (value: T[K], rowId: string) => void;
    options: {
        value: T[K];
        label: string;
    }[];
};
/**
 * Configuration for multiselect editable columns (legacy)
 * @deprecated Use editConfig instead: `editConfig: { mode: "multiselect", options: [...], onChange: ... }`
 */
type MultiselectEditableColumnConfig<T, K extends keyof T> = NonNullable<T[K]> extends unknown[] ? BaseColumnConfig<T, K> & {
    editConfig?: undefined;
    editMode: "multiselect";
    onChange?: (value: T[K], rowId: string) => void;
    options: {
        value: ArrayElement<NonNullable<T[K]>>;
        label: string;
    }[];
} : never;
/**
 * Full column configuration type - union of all possible configurations.
 * Includes both new editConfig-based and legacy editMode-based configs.
 * TypeScript will enforce that the editMode/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> | MultiselectEditConfigColumnConfig<T, K> | BooleanEditConfigColumnConfig<T, K> | TextEditableColumnConfig<T, K> | SelectEditableColumnConfig<T, K> | MultiselectEditableColumnConfig<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", { headerLabel: "Amount", type: "currency" });
 *
 * // Editable column with editConfig
 * createColumn("name", {
 *   headerLabel: "Name",
 *   type: "text",
 *   editConfig: { mode: "text", onChange: (value, rowId) => save(value, rowId) }
 * });
 *
 * // Number editing
 * createColumn("amount", {
 *   headerLabel: "Amount",
 *   editConfig: {
 *     mode: "number",
 *     minValue: 0,
 *     maxValue: 10000,
 *     step: 0.01,
 *     onChange: (value, rowId) => save(value, rowId)
 *   }
 * });
 *
 * // Select editing
 * createColumn("status", {
 *   headerLabel: "Status",
 *   editConfig: {
 *     mode: "select",
 *     options: [{ value: "active", label: "Active" }],
 *     onChange: (value, rowId) => save(value, rowId)
 *   }
 * });
 *
 * // Multiselect editing with array column
 * createColumn("tags", {
 *   headerLabel: "Tags",
 *   editConfig: {
 *     mode: "multiselect",
 *     options: [{ value: "urgent", label: "Urgent" }],
 *     onChange: (value, rowId) => save(value, rowId)
 *   }
 * });
 * ```
 */
export declare function createColumnHelper<T>(): <K extends keyof T>(id: K | {
    group: string;
}, column: ColumnConfig<T, K>) => ColumnDef<T>;
export {};
