import React, { PureComponent, ComponentProps } from 'react';
import ReactGlobalComp from 'react-global-comp';

declare enum ParamType {
    ParamGroup = -1,
    Number = 1,
    Percentage = 2,
    Bool = 3,
    NumberRange = 4,
    PercentageRange = 5,
    ExpiryLimit = 6,
    Expiry = 7,
    Phone = 8,
    Text = 9,
    ExpiryValue = 10,
    InstrumentValue = 11,
    TextNumberList = 12,
    TextPercentageList = 13,
    HardLimitHandler = 15,
    InstrumentArray = 14,
    OneWayHandler = 16,
    TenorBucketHandlerList = 17,
    ExpiryVegaAlphaByEdgeList = 18
}
interface BaseInputProps {
    value?: any;
    onChange?(val: any): void;
    onBlur?(): void;
    readonly?: boolean;
    className?: string;
    style?: any;
    [key: string]: any | undefined | null;
}
interface ValidateInfo {
    [key: string]: undefined | string | ValidateInfo;
}

declare type ParamValueStruct = Record<string, any>;
interface ParamRendererProps extends BaseInputProps {
    valueType?: ParamType;
    value?: ParamValueStruct;
    expiriesOptions?: string[];
    instrumentsOptions?: string[];
    onChange?(val: ParamValueStruct): void;
}
declare class ParamRenderer extends PureComponent<ParamRendererProps> {
    get typeConfig(): {
        name: string;
        key?: string | undefined;
        defaultValue?: any;
        Comp: React.ComponentType<BaseInputProps>;
        validator?(value: any, enableEmpty?: boolean | undefined): string;
        required?: boolean | undefined;
        sort: number;
        modalWidth?: number | undefined;
    };
    get value(): any;
    onChange: (val: any) => void;
    render(): JSX.Element;
}

interface ParentSelectorOption {
    parentId?: string | number;
    $paramId: string | number;
    name?: string;
    disabled?: boolean;
    valueType: ParamType;
    children?: ParentSelectorOption[];
    [key: string]: any;
}
interface ParentSelectorProps extends BaseInputProps {
    parentOptions?: ParentSelectorOption[];
    value?: string;
    onChange?(val: string): void;
}

interface ParamFormData {
    parentId?: string;
    $paramId?: string;
    key: string;
    name?: string;
    valueType: ParamType;
    defaultValue?: Record<string, any>;
    description?: string;
}
interface ParamFormProps {
    parentOptions: ParentSelectorProps['parentOptions'];
    allKeys: string[];
    expiriesOptions: string[];
    instrumentsOptions: string[];
    initialValues?: Partial<ParamFormData>;
    groupEditable?: boolean;
    onChange?(data: ParamFormData): void;
    onSubmit?(data: ParamFormData): any;
    onModalWidthChange?(width: number): any;
}
declare class ParamForm extends PureComponent<ParamFormProps> {
    ref: React.RefObject<any>;
    get formItems(): {
        label: string;
        name: string;
        Comp: React.ComponentType<BaseInputProps>;
        required?: boolean;
        validator?(_: any, val: any): Promise<any>;
    }[];
    onChange: (changed: any, data: any) => void;
    render(): JSX.Element;
}
declare class ParamFormModalEl extends PureComponent<ParamFormProps & Required<Pick<ParamFormProps, 'onSubmit'>>> {
    ref: React.RefObject<ParamForm>;
    state: {
        visible: boolean;
        pending: boolean;
        width: number;
    };
    get isEdit(): boolean;
    onShow: () => void;
    onHide: () => void;
    onSubmit: () => any;
    handleModalWidthChange: (width: number) => void;
    render(): JSX.Element;
}
declare class ParamFormModal {
    static el: ReactGlobalComp<ParamFormProps & Required<Pick<ParamFormProps, "onSubmit">>>;
    static show(props: Omit<ComponentProps<typeof ParamFormModalEl>, 'visible'>): Promise<void>;
    static hide(): Promise<void>;
}

interface ParamValueEditorData {
    paramId: string;
    description?: string;
    valueBefore: Record<string, any>;
    value?: Record<string, any>;
    defaultValue?: Record<string, any>;
}
interface ParamValueEditorProps {
    allParams: ParentSelectorProps['parentOptions'];
    expiriesOptions: string[];
    instrumentsOptions: string[];
    valueType: ParamType;
    initialValues: ParamValueEditorData;
    onChange?(data: ParamValueEditorData): void;
    onSubmit?(data: ParamValueEditorData): any;
    onModalWidthChange(width: number): void;
}
declare class ParamValueEditor extends PureComponent<ParamValueEditorProps> {
    ref: React.RefObject<any>;
    get formItems(): {
        label: string;
        name: string;
        className?: string;
        Comp: React.ComponentType<BaseInputProps>;
        required?: boolean;
        validator?(_: any, val: any): Promise<any>;
    }[];
    onChange: (changed: any, data: any) => void;
    render(): JSX.Element;
}
declare class ParamValueEditorModalEl extends PureComponent<ParamValueEditorProps & Required<Pick<ParamValueEditorProps, 'onSubmit'>>> {
    ref: React.RefObject<ParamValueEditor>;
    state: {
        visible: boolean;
        pending: boolean;
        width: number;
    };
    onShow: () => void;
    onHide: () => void;
    onSubmit: () => any;
    handleModalWidthChange: (width: number) => void;
    render(): JSX.Element;
}
declare class ParamValueEditorModal {
    static el: ReactGlobalComp<ParamValueEditorProps & Required<Pick<ParamValueEditorProps, "onSubmit">>>;
    static show(props: Omit<ComponentProps<typeof ParamValueEditorModalEl>, 'visible'>): Promise<void>;
    static hide(): Promise<void>;
}

interface ImageUploadProps extends BaseInputProps {
    value?: string;
    onChange?(val?: string): void;
    getSignedUrl(key: string): Promise<string>;
    /**
     * 返回图片的 key
     * */
    handleUpload(file: Blob): Promise<string>;
}

interface ParamGroupEditorData {
    parentId: string;
    $paramId?: string;
    name: string;
    valueType?: ParamType;
    descriptionUrl?: string;
}
interface ParamItem {
    parentId?: number | string;
    paramId: number | string;
    name?: string;
    key?: string;
    valueType: ParamType;
    description?: string;
    descriptionUrl?: string;
    rank?: number;
    value?: Record<string, any>;
    defaultValue?: Record<string, any>;
    children?: ParamItem[];
}
interface LocalParamItem extends Omit<ParamItem, 'paramId' | 'children' | 'childrenList'> {
    paramId?: number | string;
    /**
     * 前端字段，用于本地建立参数与参数组之间的关系
     * 提交到服务端不解析
     * */
    $paramId: number | string;
    children?: LocalParamItem[];
}
interface ParamGroupEditorProps extends Required<Pick<ImageUploadProps, 'getSignedUrl' | 'handleUpload'>> {
    /**
     * 传了表示为有父级
     * */
    parentOptions?: ParentSelectorProps['parentOptions'];
    initialValues?: Partial<ParamGroupEditorData>;
    paramList: LocalParamItem[];
    projectName: string;
    templateName: string;
    parentNames?: string;
    onChange?(data: ParamGroupEditorData): void;
    onSubmit?(data: ParamGroupEditorData): any;
}
declare class ParamGroupEditor extends PureComponent<ParamGroupEditorProps> {
    ref: React.RefObject<any>;
    get formItems(): {
        label: string;
        name: string;
        Comp: React.ComponentType<BaseInputProps>;
        required?: boolean | undefined;
        validator?(_: any, val: any): Promise<any>;
    }[];
    onChange: (changed: any, data: any) => void;
    render(): JSX.Element;
}
declare class ParamGroupEditorModalEl extends PureComponent<ParamGroupEditorProps & Required<Pick<ParamGroupEditorProps, 'onSubmit'>>> {
    ref: React.RefObject<ParamGroupEditor>;
    state: {
        visible: boolean;
        pending: boolean;
    };
    get isEdit(): boolean;
    onShow: () => void;
    onHide: () => void;
    onSubmit: () => any;
    render(): JSX.Element;
}
declare class ParamGroupEditorModal {
    static el: ReactGlobalComp<ParamGroupEditorProps & Required<Pick<ParamGroupEditorProps, "onSubmit">>>;
    static show(props: Omit<ComponentProps<typeof ParamGroupEditorModalEl>, 'visible'>): Promise<void>;
    static hide(): Promise<void>;
}

interface ParamMoverData {
    parentId: string | number;
}
interface ParamMoverProps {
    /**
     * 需要确保 targetParams 的元素之间无父子或者祖先子孙关系
     * */
    targetParams: (string | number)[];
    allParams: NonNullable<ParentSelectorProps['parentOptions']>;
    /**
     * 最大层级(包括参数)
     * @default 3
     * */
    maxLevel?: number;
    onSubmit?(params: NonNullable<ParentSelectorProps['parentOptions']>): any;
}
declare function initState(props: ParamMoverProps): {
    preProps: ParamMoverProps;
    options: any[];
    paramsMap: Record<string, ParentSelectorOption>;
};
declare type ParamMoverState = ReturnType<typeof initState>;
declare class ParamMover extends PureComponent<ParamMoverProps, ParamMoverState> {
    static getDerivedStateFromProps(props: ParamMoverProps, state: ParamMoverState): {
        preProps: ParamMoverProps;
        options: any[];
        paramsMap: Record<string, ParentSelectorOption>;
    };
    get newParams(): ParentSelectorOption[];
    state: {
        preProps: ParamMoverProps;
        options: any[];
        paramsMap: Record<string, ParentSelectorOption>;
    };
    ref: React.RefObject<any>;
    get formItems(): {
        label: string;
        name: string;
        Comp: React.ComponentType<BaseInputProps>;
        required?: boolean | undefined;
        validator?(_: any, val: any): Promise<any>;
    }[];
    render(): JSX.Element;
}
declare class ParamMoverModalEl extends PureComponent<ParamMoverProps & Required<Pick<ParamMoverProps, 'onSubmit'>>> {
    ref: React.RefObject<ParamMover>;
    state: {
        visible: boolean;
        pending: boolean;
    };
    onShow: () => void;
    onHide: () => void;
    onSubmit: () => any;
    render(): JSX.Element;
}
declare class ParamMoverModal {
    static el: ReactGlobalComp<ParamMoverProps & Required<Pick<ParamMoverProps, "onSubmit">>>;
    static show(props: Omit<ComponentProps<typeof ParamMoverModalEl>, 'visible'>): Promise<void>;
    static hide(): Promise<void>;
}

declare const ParamTypeConfig: Record<ParamType, {
    name: string;
    key?: string;
    defaultValue?: any;
    Comp: React.ComponentType<BaseInputProps>;
    validator?(value: any, enableEmpty?: boolean): string;
    required?: boolean;
    sort: number;
    modalWidth?: number;
}>;
declare function paramValidator(val: any, values: {
    valueType: ParamType;
}, enableEmpty?: boolean): string;
declare const ParamTypeOptions: {
    value: number;
    label: string;
    name: string;
    key?: string | undefined;
    defaultValue?: any;
    Comp: React.ComponentType<BaseInputProps>;
    validator?(value: any, enableEmpty?: boolean | undefined): string;
    required?: boolean | undefined;
    sort: number;
    modalWidth?: number | undefined;
}[];

declare function formatNum(val: string): number | undefined;
declare function isNullLike(val: any): val is undefined | null;
declare function isEmpty(val: any): val is undefined | null;
declare function emptyValidator(val: any, enableEmpty?: boolean): "Should not be empty" | "";
declare function numRangeValidator(val: {
    min?: string;
    max?: string;
}, enableEmpty?: boolean): string;
declare function expiryValidator(val: string, enableEmpty?: boolean): "Should not be empty" | "";
declare function expiriesValidator(val: string[]): string;
declare function keyValidator(val: string, allKeys: string[]): "Should not be empty" | "" | "Out of format: should be a combination of the following chars `_.0-9a-zA-Z`" | "This key has been used";
declare function isExpired(val?: string): boolean;
declare function sameGroupNameValidator(val: string, paramList: LocalParamItem[], projectName: string, templateName: string, parentNames?: string): string;
declare function validatorCvt(validator: (val: any, values: any) => ValidateInfo['string'], form?: () => any): (_: any, val: any) => Promise<any>;

export { BaseInputProps, LocalParamItem, ParamForm, ParamFormData, ParamFormModal, ParamFormProps, ParamGroupEditor, ParamGroupEditorData, ParamGroupEditorModal, ParamGroupEditorModalEl, ParamGroupEditorProps, ParamItem, ParamMover, ParamMoverData, ParamMoverModal, ParamMoverModalEl, ParamMoverProps, ParamMoverState, ParamRenderer, ParamRendererProps, ParamType, ParamTypeConfig, ParamTypeOptions, ParamValueEditor, ParamValueEditorData, ParamValueEditorModal, ParamValueEditorModalEl, ParamValueEditorProps, ParamValueStruct, ValidateInfo, emptyValidator, expiriesValidator, expiryValidator, formatNum, isEmpty, isExpired, isNullLike, keyValidator, numRangeValidator, paramValidator, sameGroupNameValidator, validatorCvt };
