export interface ValidationRule {
    pattern?: string | RegExp;
    message?: string;
    required?: boolean | ((formValues?: any) => boolean);
    minLength?: number;
    maxLength?: number;
    min?: number | string | {
        field: string;
        message?: string;
    };
    max?: number | string | {
        field: string;
        message?: string;
    };
    custom?: (value: any, formValues?: any) => boolean | string;
}
export interface ApiConfig {
    endpoint: string;
    method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
    valueField?: string;
    labelField?: string;
    headers?: Record<string, string>;
    params?: Record<string, any>;
    body?: any;
    transform?: (data: any[]) => Array<{
        label: string;
        value: string | number;
    }>;
    dependsOn?: string;
    conditional?: boolean;
    passThroughFields?: string[];
}
export interface BaseField {
    id?: string;
    title?: string;
    name: string;
    label: string;
    type: 'text' | 'email' | 'password' | 'number' | 'tel' | 'mobile' | 'select' | 'checkbox' | 'checkboxGroup' | 'toggle' | 'radio' | 'switch' | 'autocomplete' | 'date' | 'textarea' | 'image' | 'title' | 'section' | 'component' | 'finuiHeader' | 'tabs' | 'grid' | 'listcards' | 'dragdroplist';
    placeholder?: string;
    labelPosition?: 'inner' | 'top' | 'none';
    labelVariant?: 'caption' | 'body2' | 'subtitle2' | 'h6';
    required?: boolean | ((formValues?: any) => boolean);
    disabled?: boolean;
    copyWhenDisabled?: boolean;
    passThroughFields?: string[];
    helperText?: string;
    validation?: ValidationRule;
    step?: number;
    value?: any | ((form: any) => any);
    valueDeps?: string[];
    col?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
    xs?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
    sm?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
    md?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
    lg?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
    xl?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
    api_endpoint?: string;
    api_method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
    value_field?: string;
    label_field?: string;
    depends_on?: string;
    conditional?: boolean;
    apiConfig?: ApiConfig;
    showWhen?: ((formData: any) => boolean) | {
        field: string;
        equals: any;
    } | {
        field: string;
        in: any[];
    };
}
export interface TextField extends BaseField {
    type: 'text' | 'email' | 'password' | 'tel' | 'textarea';
    minLength?: number;
    maxLength?: number;
    pattern?: string;
}
export interface NumberField extends BaseField {
    type: 'number';
    min?: number;
    max?: number;
}
/** Mobile phone with dial-code dropdown; store value is national store-format string (not E.164). */
export interface MobileField extends BaseField {
    type: 'mobile';
    minLength?: number;
    maxLength?: number;
    pattern?: string;
    /** Dial-code options (digits without "+"), e.g. [{ dial_code: "260", label: "ZM" }] */
    dialCodes?: Array<{
        dial_code: string;
        label?: string;
        iso?: string;
    }>;
    /** Default dial code digits without "+" */
    defaultDialCode?: string;
    /** Optional national prefix allowlist */
    mobilePrefixes?: string[];
    /** Expected store shape, e.g. "0XXXXXXXXX" */
    storeFormat?: string;
    /** Example strings for helper / paste hints */
    phoneExamples?: string[];
}
export interface SelectField extends BaseField {
    type: 'select';
    options?: Array<{
        label: string;
        value: string | number;
    }>;
    default?: string | number;
    api_endpoint?: string;
    api_method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
    value_field?: string;
    label_field?: string;
    depends_on?: string;
    conditional?: boolean;
    apiConfig?: ApiConfig;
}
export interface CheckboxField extends BaseField {
    type: 'checkbox';
}
export interface ToggleField extends BaseField {
    type: 'toggle';
    options: Array<{
        label: string;
        value: string | number;
    }>;
}
export interface RadioField extends BaseField {
    type: 'radio';
    options: Array<{
        label: string;
        value: string | number;
        description?: string;
    }>;
    row?: boolean;
    groupPadding?: number;
    itemGap?: number;
    helperText?: string;
}
export interface CheckboxGroupField extends BaseField {
    type: 'checkboxGroup';
    options: Array<{
        label: string;
        value: string | number;
    }>;
    row?: boolean | number;
    groupPadding?: number;
    itemGap?: number;
    helperText?: string;
}
export interface SwitchField extends BaseField {
    type: 'switch';
}
export interface AutocompleteField extends BaseField {
    type: 'autocomplete';
    options?: Array<{
        label: string;
        value: string | number;
    }>;
    multiple?: boolean;
    freeSolo?: boolean;
    filterOptions?: boolean;
    selectedAssignments?: Record<string, string>;
    api_endpoint?: string;
    api_method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
    value_field?: string;
    label_field?: string;
    depends_on?: string;
    conditional?: boolean;
    apiConfig?: ApiConfig;
}
export interface DateField extends BaseField {
    type: 'date';
    minDate?: string;
    maxDate?: string;
    /** Per-field dayjs format override (e.g. DD-MM-YYYY). Falls back to FinForm dateFormat. */
    dateFormat?: string;
}
export interface ImageField extends BaseField {
    type: 'image';
    src?: string;
    alt?: string;
    width?: number | string;
    height?: number | string;
    style?: React.CSSProperties;
    className?: string;
    onClick?: () => void;
    defaultValue?: string;
    accept?: string | string[];
    onFileSelected?: (file: File) => void;
    onRemove?: () => void;
    onPreview?: (url: string) => void;
    onSave?: (payload: {
        url: string;
        file?: File;
    }) => void;
    imagePlaceholder?: {
        icon?: 'upload' | 'image';
        title?: string;
        subtitle?: string;
        buttonText?: string;
        helperText?: string;
        sx?: any;
        iconSx?: any;
        titleSx?: any;
        subtitleSx?: any;
        buttonSx?: any;
        helperTextSx?: any;
    };
    imageUploaded?: {
        previewText?: string;
        removeText?: string;
        saveText?: string;
        showSave?: boolean;
        previewTitle?: string;
        replaceText?: string;
        closeText?: string;
        cardSx?: any;
        thumbnailSx?: any;
        fileNameSx?: any;
        fileMetaSx?: any;
        previewButtonSx?: any;
        removeButtonSx?: any;
        saveButtonSx?: any;
    };
}
export interface ComponentField extends BaseField {
    type: 'component';
    content?: React.ReactNode;
    render?: () => React.ReactNode;
}
export interface TitleField extends BaseField {
    type: 'title';
    variant?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
    color?: string;
    align?: 'left' | 'center' | 'right';
    sx?: any;
}
export interface SectionField extends BaseField {
    type: 'section';
    variant?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
    color?: string;
    align?: 'left' | 'center' | 'right';
    sx?: any;
    cardWrap?: boolean;
    cardSx?: any;
    cardProps?: any;
}
export interface FinUiHeaderField extends BaseField {
    type: 'finuiHeader';
    title?: string;
    subtitle?: string;
    align?: 'left' | 'center' | 'right';
    actions?: any;
    actionName?: string;
    actionComponent?: 'switch' | 'checkbox';
    actionLabel?: string;
    cardWrap?: boolean;
    cardSx?: any;
    cardProps?: any;
}
export interface TabsField extends BaseField {
    type: 'tabs';
    items: Array<{
        label: React.ReactNode;
        value?: string | number | React.ReactNode;
        content?: React.ReactNode;
        disabled?: boolean;
        fields?: FieldConfig[];
    }>;
    defaultValue?: any;
    tabSx?: any;
}
export interface GridField extends BaseField {
    type: 'grid';
    initialRow: Record<string, any>;
    columns: Array<{
        key: string;
        header: string;
        type?: 'text' | 'number' | 'select' | 'checkbox' | 'date' | 'index';
        width?: number | string | 'auto';
        options?: {
            label: string;
            value: any;
        }[];
        placeholder?: string;
        disabled?: boolean | ((row: any, index: number) => boolean);
        value?: any | ((row: any, index: number) => any);
        editable?: boolean;
        indexFormat?: (index: number) => string;
        helperText?: string;
        required?: boolean;
        minLength?: number;
        maxLength?: number;
        pattern?: string;
        min?: number;
        max?: number;
        step?: number;
        endorsementText?: string | ((row: any, index: number) => string);
        endorsementBg?: string;
        endorsementColor?: string;
        endorsementRadius?: number | string;
        endorsementHeight?: number;
        endorsementPaddingX?: number;
        apiConfig?: {
            endpoint: string;
            method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
            valueField?: string;
            labelField?: string;
            headers?: Record<string, string>;
            params?: Record<string, any>;
            body?: any;
            transform?: (data: any[]) => Array<{
                label: string;
                value: string | number;
            }>;
            dependsOn?: string;
            conditional?: boolean;
            passThroughFields?: string[];
        };
        sx?: any;
        cellSx?: any;
    }>;
    addLabel?: string;
    rowDeletable?: boolean;
    addActions?: {
        label: string;
        template: Record<string, any>;
    }[];
    emptyTitle?: string;
    emptySubtitle?: string;
    emptyCardSx?: any;
}
export interface ListCardsField extends BaseField {
    type: 'listcards';
    items: Array<{
        id: string | number;
        header?: string;
        chipText?: string;
        leftAction?: {
            name: string;
            label?: string;
        };
        rightAction?: {
            name: string;
            label?: string;
        };
    }>;
    sx?: any;
    cardSx?: any;
}
export interface DragDropListField extends Omit<BaseField, 'helperText'> {
    type: 'dragdroplist';
    items: any[];
    getId?: string | ((item: any) => string | number);
    getText?: string | ((item: any) => string);
    header?: React.ReactNode;
    chipText?: string | ((item: any, index: number) => string | undefined);
    showIndex?: boolean;
    showLeftIcon?: boolean;
    renderItem?: (item: any, isDragging: boolean) => React.ReactNode;
    helperText?: React.ReactNode | string;
    sx?: any;
}
export type FieldConfig = TextField | NumberField | MobileField | SelectField | CheckboxField | CheckboxGroupField | ToggleField | RadioField | SwitchField | AutocompleteField | DateField | ImageField | TitleField | SectionField | ComponentField | FinUiHeaderField | TabsField | GridField | ListCardsField | DragDropListField;
export type AutomationFieldConfig = FieldConfig & {
    testId?: string;
    automation?: {
        skip?: boolean;
        fieldTestId?: string;
        inputTestId?: string;
        labelTestId?: string;
        errorTestId?: string;
        sampleValue?: unknown;
        invalidValue?: unknown;
    };
};
export interface FormButton {
    text: string;
    color?: string;
    size?: 'small' | 'medium' | 'large';
    onClick?: () => void;
    disabled?: boolean;
    loading?: boolean;
    position?: 'left' | 'center' | 'right' | 'space-between';
    type?: 'submit' | 'button' | 'reset';
    sx?: any;
}
export interface ButtonGroup {
    buttons: FormButton[];
    position?: 'left' | 'center' | 'right' | 'space-between';
    layout?: 'horizontal' | 'vertical';
    spacing?: number;
    sx?: any;
}
export interface FormTitle {
    text: string;
    variant?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
    color?: string;
    align?: 'left' | 'center' | 'right';
    sx?: any;
}
export interface FormTheme {
    primaryColor?: string;
    secondaryColor?: string;
    backgroundColor?: string;
    textColor?: string;
    borderRadius?: number | string;
    spacing?: number;
    typography?: {
        fontFamily?: string;
        fontSize?: number | string;
    };
}
export interface FinFormProps {
    id?: string;
    title?: FormTitle;
    theme?: FormTheme;
    fields: FieldConfig[];
    onSubmit: (data: any) => void;
    onChange?: (data: any) => void;
    submitButtonText?: string;
    onSubmitClick?: (data: any) => void;
    defaultValues?: Record<string, any>;
    showSubmitButton?: boolean;
    buttons?: FormButton[];
    buttonGroup?: ButtonGroup;
    stickyButtons?: boolean;
    stickyButtonsSx?: any;
    fixedButtons?: boolean;
    fixedButtonsSx?: any;
    formCardWrap?: boolean;
    formCardSx?: any;
    formCardProps?: any;
    baseUrl?: string;
    apiHeaders?: Record<string, string>;
    isMultiStep?: boolean;
    currentStep?: number;
    onStepChange?: (currentStep: number, totalSteps: number) => void;
    showStepNavigation?: boolean;
    stepNavigationProps?: {
        showStepTitles?: boolean;
        stepTitles?: string[];
    };
    /** Prefix for stable data-testid attributes on generated form controls (e.g. "client-profile"). */
    testIdPrefix?: string;
    /**
     * Dayjs format for all date fields (e.g. DD-MM-YYYY, MM-DD-YYYY, YYYY-MM-DD).
     * Host app should map company regional settings to this value.
     */
    dateFormat?: string;
}
export interface FieldRendererProps {
    field: FieldConfig;
    control: any;
    errors: any;
    baseUrl?: string;
    apiHeaders?: Record<string, string>;
    formData?: Record<string, any>;
    setValue?: (name: string, value: any, options?: any) => void;
    testIdPrefix?: string;
    /** Form-level dayjs date format inherited by date fields. */
    dateFormat?: string;
}
export interface FinInputTestIdProps {
    inputTestId?: string;
    labelTestId?: string;
    errorTestId?: string;
    optionTestId?: (optionValue: string | number) => string;
}
export interface StepNavigationProps {
    currentStep: number;
    totalSteps: number;
    onStepChange: (step: number) => void;
    stepTitles?: string[];
    showStepTitles?: boolean;
    completedSteps?: number[];
}
