import type { Api, BaseSchemaWithoutType, GridSizeUnit, GridSizeUnitStr, RendererConfig, RendererProps, Schema, SchemaBoolean, SchemaClassName, SchemaExpression, TestFunc } from 'jamis-core';
import type { SchemaRemark } from '../types';
import type { FormHorizontal, FormOptionsControl, FormSchemaBase, IFormItemStore, IFormStore } from './types';
export interface FormBaseControl extends BaseSchemaWithoutType {
    /**
     * 表单项大小
     */
    size?: SizeUnit;
    sizeExpr?: SchemaExpression;
    /**
     * 描述标题
     */
    label?: string | false | Schema;
    /**
     * 描述标题
     */
    labelAlign?: LabelAlign;
    /**
     * label自定义宽度，默认单位为px
     */
    labelWidth?: number | string;
    /**
     * 配置 label className
     */
    labelClassName?: string;
    /**
     * 字段名，表单提交时的 key，支持多层级，用.连接，如： a.b.c
     */
    name?: string;
    /**
     * 显示一个小图标, 鼠标放上去的时候显示提示内容
     */
    remark?: unknown;
    /**
     * 显示一个小图标, 鼠标放上去的时候显示提示内容, 这个小图标跟 label 在一起
     */
    labelRemark?: unknown;
    /**
     * 输入提示，聚焦的时候显示
     */
    hint?: string;
    /**
     * 当修改完的时候是否提交表单。
     */
    submitOnChange?: boolean;
    /**
     * 是否只读
     */
    readOnly?: boolean;
    /**
     * 只读条件
     */
    readOnlyOn?: string;
    /**
     * 不设置时，当表单提交过后表单项每次修改都会触发重新验证，
     * 如果设置了，则由此配置项来决定要不要每次修改都触发验证。
     */
    validateOnChange?: boolean;
    /**
     * 是否要开启校验, 默认会开启
     * 这只是一个开关, 实际上要有设置校验规则时才真正做校验
     */
    validatable?: boolean;
    /**
     * 是否要开启校验表达式
     */
    validatableOn?: SchemaExpression;
    /**
     * 描述内容，支持 Html 片段。
     */
    description?: string;
    /**
     * @deprecated 用 description 代替
     */
    desc?: string;
    /**
     * 配置描述上的 className
     */
    descriptionClassName?: SchemaClassName;
    /**
     * 配置当前表单项展示模式
     */
    mode?: 'normal' | 'inline' | 'horizontal';
    modeExpr?: SchemaExpression;
    /**
     * 当配置为水平布局的时候，用来配置具体的左右分配。
     */
    horizontal?: FormHorizontal;
    /**
     * 表单 control 是否为 inline 模式。
     */
    inline?: boolean;
    /**
     * control元素的 className
     */
    inputClassName?: SchemaClassName;
    /**
     * control元素的 style
     */
    inputStyle?: React.CSSProperties;
    /**
     * control下子元素的样式类
     */
    controlBodyClassName?: SchemaClassName;
    /**
     * 占位符
     */
    placeholder?: string;
    placeholderExpr?: SchemaExpression;
    /**
     * 是否为必填
     */
    required?: boolean;
    /**
     * 动态判断是否为必填
     */
    requiredOn?: SchemaExpression;
    /**
     * 必填星号的样式类
     */
    requiredClassName?: SchemaClassName;
    changeImmediately?: boolean;
    /**
     * 验证失败的提示信息
     */
    validationErrors?: {
        [k in keyof FormValidation]: string;
    };
    validations?: string | FormValidation;
    /**
     * 默认值，切记只能是静态值，不支持取变量，跟数据关联是通过设置 name 属性来实现的。
     */
    value?: any;
    /**
     * 表单项隐藏时，是否在当前 Form 中删除掉该表单项值。注意同名的未隐藏的表单项值也会删掉
     */
    clearValueOnHidden?: boolean;
    /**
     * 远端校验表单项接口
     */
    validateApi?: Api;
    /** 是否可清除 */
    clearable?: boolean;
    /** 设置列占据的行宽, 1-12 */
    columnRatio?: GridSizeUnit;
    columnRatioExpr?: GridSizeUnit | SchemaExpression | Record<GridSizeUnitStr, boolean | SchemaBoolean>;
    /**
     * 是否静态展示
     */
    static?: boolean;
    /**
     * 是否静态展示表达式
     */
    staticOn?: SchemaExpression;
    /**
     * 静态展示空值占位
     */
    staticPlaceholder?: string;
    /**
     * 静态展示表单项类名
     */
    staticClassName?: SchemaClassName;
    /**
     * 静态展示表单项Label类名
     */
    staticLabelClassName?: SchemaClassName;
    /**
     * 静态展示表单项Value类名
     */
    staticInputClassName?: SchemaClassName;
    staticSchema?: any;
    /** 兼容老用法，新用法直接在 Component 里面定义 validate 方法即可。 */
    validate?: (values: any, value: any) => string | boolean;
    /**
     * 表单项值读取时的转换函数或者表达式字符串, 用于getValue
     */
    pipeIn?: ((value: any, data: Record<string, any>) => any) | SchemaExpression;
    /**
     * 每次值改变而写入时转换函数或者表达式字符串, 用于handleChange
     */
    pipeOut?: ((value: any, originValue: any, data: Record<string, any>) => any) | SchemaExpression;
}
export interface FormBaseControlSchema extends FormBaseControl {
    /**
     * 显示一个小图标, 鼠标放上去的时候显示提示内容
     */
    remark?: SchemaRemark;
    /**
     * 显示一个小图标, 鼠标放上去的时候显示提示内容, 这个小图标跟 label 在一起
     */
    labelRemark?: SchemaRemark;
    /**
     * 是否显示清除按钮
     */
    clearable?: boolean;
}
export interface FormOptionsSchema extends FormBaseControlSchema, Omit<FormOptionsControl, 'remark' | 'labelRemark'> {
}
export interface FormItemBasicConfig extends Partial<RendererConfig> {
    type?: string;
    wrap?: boolean;
    renderLabel?: boolean;
    renderDescription?: boolean;
    test?: RegExp | TestFunc;
    storeType?: string;
    validations?: string;
    /**
     * 是否使用严格模式, 默认是true, 如果设置为false, 则任何属性变化都执行re-render
     */
    strictMode?: boolean;
    /**
     * schema变化使视图更新的属性白名单
     */
    detectProps?: Array<string>;
    descriptionClassName?: string;
    storeExtendsData?: boolean;
    sizeMutable?: boolean;
    weight?: number;
    extendsData?: boolean;
    showErrorMsg?: boolean;
    shouldComponentUpdate?: (props: any, prevProps: any) => boolean;
    validate?: (values: any, value: any) => string | boolean;
}
export interface FormItemProps extends RendererProps {
    name?: string;
    formStore?: IFormStore;
    formItem?: IFormItemStore;
    formInited: boolean;
    formMode: 'normal' | 'horizontal' | 'inline' | 'row' | 'default';
    formHorizontal: FormHorizontal;
    horizontal?: FormHorizontal;
    formLabelAlign: LabelAlign;
    formLabelWidth?: number | string;
    defaultSize?: SizeUnit;
    size?: SizeUnit;
    labelAlign?: LabelAlign;
    labelWidth?: number | string;
    labelClassName?: string;
    disabled?: boolean;
    btnDisabled: boolean;
    defaultValue: any;
    value?: any;
    prinstine: any;
    formItemValue: any;
    inputClassName?: string;
    inputStyle?: React.CSSProperties;
    inputOnly?: boolean;
    renderLabel?: boolean;
    renderDescription?: boolean;
    sizeMutable?: boolean;
    wrap?: boolean;
    hint?: string;
    description?: string;
    descriptionClassName?: string;
    errors?: {
        [propName: string]: string;
    };
    error?: string;
    showErrorMsg?: boolean;
    requiredClassName?: SchemaClassName;
    valueClassName?: SchemaClassName;
    setPrinstineValue: (value: any) => void;
    onChange: (value: any, submitOnChange?: boolean, changeImmediately?: boolean) => void;
    onBulkChange?: (values: {
        [propName: string]: any;
    }, submitOnChange?: boolean) => void;
    addHook: (fn: Function, mode: 'validate' | 'init' | 'flush') => () => void;
    removeHook: (fn: Function, mode?: 'validate' | 'init' | 'flush') => void;
    renderFormItems: (schema: Partial<FormSchemaBase>, region: string, props: any) => JSX.Element;
    onFocus: (e: any) => void;
    onBlur: (e: any) => void;
    getValue: () => any;
    setValue: (value: any, key: string) => void;
    renderControl?: (props: FormControlProps) => JSX.Element;
}
export type FormControlProps = RendererProps & {
    onOpenDialog: (schema: Schema, data: any) => Promise<any>;
} & Exclude<FormItemProps, 'inputClassName' | 'renderControl' | 'defaultSize' | 'size' | 'error' | 'errors' | 'hint' | 'descriptionClassName' | 'inputOnly' | 'renderLabel' | 'renderDescription' | 'sizeMutable' | 'wrap'>;
export type FormItemComponent = React.ComponentType<FormItemProps>;
export type FormControlComponent = React.ComponentType<FormControlProps>;
export interface FormItemConfig extends FormItemBasicConfig {
    component: FormControlComponent;
}
export interface FormItemStoreProp {
    required?: boolean;
    readOnly?: boolean;
    disabled?: boolean;
    unique?: boolean;
    value?: any;
    rules?: string | {
        [propName: string]: any;
    };
    messages?: {
        [propName: string]: string;
    } | string | {};
    multiple?: boolean;
    delimiter?: string;
    valueField?: string;
    labelField?: string;
    joinValues?: boolean;
    extractValue?: boolean;
    type?: string;
    id?: string;
    selectFirst?: boolean;
    autoFill?: any;
    clearValueOnHidden?: boolean;
    validateApi?: boolean | string;
    minLength?: number;
    maxLength?: number;
    validateOnChange?: boolean;
    label?: string;
    resetValue: string;
    isValueSchemaExp?: boolean;
    inputGroupControl?: {
        name: string;
        path: string;
        [propsName: string]: any;
    };
    [key: string]: any;
}
export interface FormValidation {
    /**
     * 是否是字母
     */
    isAlpha?: boolean;
    /**
     * 是否为字母数字
     */
    isAlphanumeric?: boolean;
    /**
     * 是否为邮箱地址
     */
    isEmail?: boolean;
    /**
     * 是否为浮点型
     */
    isFloat?: boolean;
    /**
     * 是否为整型
     */
    isInt?: boolean;
    /**
     * 是否为 json
     */
    isJson?: boolean;
    /**
     * 长度等于指定值
     */
    isLength?: number;
    /**
     * 是否为数字
     */
    isNumeric?: boolean;
    /**
     * 是否为必填
     */
    isRequired?: boolean;
    /**
     * 是否为 URL 地址
     */
    isUrl?: boolean | {
        schemes?: ('http' | 'https' | 'ftp' | 'sftp' | 'file')[];
        allowLocal?: boolean;
        allowDataUrl?: boolean;
    };
    /**
     * 内容命中指定正则
     */
    matchRegexp?: string | RegExp;
    /**
     * 内容命中指定正则
     */
    matchRegexp1?: string | RegExp;
    /**
     * 内容命中指定正则
     */
    matchRegexp2?: string | RegExp;
    /**
     * 内容命中指定正则
     */
    matchRegexp3?: string | RegExp;
    /**
     * 内容命中指定正则
     */
    matchRegexp4?: string | RegExp;
    /**
     * 内容命中指定正则
     */
    matchRegexp5?: string | RegExp;
    /**
     * 内容命中指定正则
     */
    matchRegexp6?: string | RegExp;
    /**
     * 内容命中指定正则
     */
    matchRegexp7?: string | RegExp;
    /**
     * 内容命中指定正则
     */
    matchRegexp8?: string | RegExp;
    /**
     * 内容命中指定正则
     */
    matchRegexp9?: string | RegExp;
    /**
     * 最大长度为指定值
     */
    maxLength?: number | string;
    /**
     * 最大值为指定值
     */
    maximum?: number | string;
    /**
     * 最小长度为指定值
     */
    minLength?: number | string;
    /**
     * 最小值为指定值
     */
    minimum?: number | string;
    /**
     * 和目标日期相同，支持指定粒度，默认到毫秒
     * @version 2.2.0
     */
    isDateTimeSame?: string | string[];
    /**
     * 早于目标日期，支持指定粒度，默认到毫秒
     * @version 2.2.0
     */
    isDateTimeBefore?: string | string[];
    /**
     * 晚于目标日期，支持指定粒度，默认到毫秒
     * @version 2.2.0
     */
    isDateTimeAfter?: string | string[];
    /**
     * 早于目标日期或和目标日期相同，支持指定粒度，默认到毫秒
     * @version 2.2.0
     */
    isDateTimeSameOrBefore?: string | string[];
    /**
     * 晚于目标日期或和目标日期相同，支持指定粒度，默认到毫秒
     * @version 2.2.0
     */
    isDateTimeSameOrAfter?: string | string[];
    /**
     * 日期处于目标日期范围，支持指定粒度和区间的开闭形式，默认到毫秒, 左右开区间
     * @version 2.2.0
     */
    isDateTimeBetween?: string | string[];
    /**
     * 和目标时间相同，支持指定粒度，默认到毫秒
     * @version 2.2.0
     */
    isTimeSame?: string | string[];
    /**
     * 早于目标时间，支持指定粒度，默认到毫秒
     * @version 2.2.0
     */
    isTimeBefore?: string | string[];
    /**
     * 晚于目标时间，支持指定粒度，默认到毫秒
     * @version 2.2.0
     */
    isTimeAfter?: string | string[];
    /**
     * 早于目标时间或和目标时间相同，支持指定粒度，默认到毫秒
     * @version 2.2.0
     */
    isTimeSameOrBefore?: string | string[];
    /**
     * 晚于目标时间或和目标时间相同，支持指定粒度，默认到毫秒
     * @version 2.2.0
     */
    isTimeSameOrAfter?: string | string[];
    /**
     * 时间处于目标时间范围，支持指定粒度和区间的开闭形式，默认到毫秒, 左右开区间
     * @version 2.2.0
     */
    isTimeBetween?: string | string[];
    [propName: string]: any;
}
export type LabelAlign = 'right' | 'left';
export type SizeUnit = 'xs' | 'sm' | 'normal' | 'md' | 'lg' | 'xl' | 'full';
export interface IOption {
    value?: string | number | null;
    label?: string | null;
    children?: IOption[] | null;
    disabled?: boolean | null;
    visible?: boolean | null;
    hidden?: boolean | null;
}
