import * as React from "react";
import * as PropTypes from "prop-types";
import { FailedBackgroundJobsPanel } from "./components";
import { ReactUtilsType } from "../utils";
import { Theme } from "../themes/theme";
import { ContextProps } from "../ReactContext";
import Form from "@rjsf/core";
import { Field, Widget, TemplatesType, ErrorSchema } from "@rjsf/utils";
import ApiClient, { ApiClientImplementation } from "../ApiClient";
import KeyHandlerService, { ShortcutKeys } from "../services/key-handler-service";
import SettingsService, { Settings } from "../services/settings-service";
import FocusService from "../services/focus-service";
import BlockerService from "../services/blocker-service";
import CustomEventService from "../services/custom-event-service";
import SubmitHookService, { SubmitHook } from "../services/submit-hook-service";
import DOMIdService from "../services/dom-id-service";
import IdService from "../services/id-service";
import RootInstanceService from "../services/root-instance-service";
import SingletonMapService from "../services/singleton-map-service";
import { FieldProps, HasMaybeChildren, JSONSchema, Lang } from "../types";
import MultiActiveArrayService from "../services/multi-active-array-service";
import * as fields from "./fields";
import * as widgets from "./widgets";
import * as templates from "./templates";
export interface LajiFormProps extends HasMaybeChildren {
    apiClient?: ApiClientImplementation;
    lang?: Lang;
    formData?: any;
    schema?: any;
    uiSchema?: any;
    topOffset?: number;
    bottomOffset?: number;
    formContext?: any;
    uiSchemaContext?: UiSchemaContext;
    settings?: any;
    id?: string;
    googleApiKey?: string;
    notifier?: Notifier;
    fields?: {
        [name: string]: Field;
    };
    widgets?: {
        [name: string]: Widget;
    };
    templates?: {
        [name: string]: TemplatesType;
    };
    autoFocus?: boolean;
    componentDidMount?: () => void;
    onError?: (e: Error, i: React.ErrorInfo) => void;
    onChange?: (formData: any) => void;
    optimizeOnChange?: boolean;
    showShortcutButton?: boolean;
    renderSubmit?: boolean;
    submitText?: string;
    onSubmit?: (data: {
        formData: any;
    }) => void;
    onValidationError?: (extraErrors: ErrorSchema) => void;
    validators?: any;
    warnings?: any;
    onSettingsChange?: (settings: any) => void;
    mediaMetadata?: MediaMetadata;
    theme?: Theme;
    lajiGeoServerAddress?: string;
    extraErrors?: ErrorSchema;
}
export interface LajiFormState {
    submitHooks?: SubmitHook[];
    formContext: FormContext;
    formData?: any;
    extraErrors?: ErrorSchema;
    externalErrors?: ErrorSchema;
    error?: boolean;
    runningSubmitHooks?: boolean;
}
export interface MediaMetadata {
    capturerVerbatim?: string | string[];
    intellectualOwner: string;
    intellectualRights: string;
}
export interface FormContext {
    translations: ByLang;
    lang: Lang;
    uiSchemaContext: any;
    formRef: React.RefObject<Form>;
    topOffset: number;
    bottomOffset: number;
    formID: string;
    googleApiKey: string;
    notifier: Notifier;
    apiClient: ApiClient;
    Label: React.ComponentType<{
        label?: string;
        id: string;
        uiSchema?: any;
        required?: boolean;
    }>;
    formDataTransformers?: {
        props: FieldProps;
        "ui:field": string;
        targets: string[];
    }[];
    _parentLajiFormId?: number;
    mediaMetadata?: MediaMetadata;
    contextId: number;
    theme: Theme;
    setTimeout: (fn: () => void, time?: number) => void;
    utils: ReactUtilsType;
    lajiGeoServerAddress: string;
    globals: Record<string, unknown>;
    services: {
        keyHandler: KeyHandlerService;
        settings: SettingsService;
        focus: FocusService;
        blocker: BlockerService;
        customEvents: CustomEventService;
        submitHooks: SubmitHookService;
        DOMIds: DOMIdService;
        ids: IdService;
        rootInstance: RootInstanceService;
        singletonMap: SingletonMapService;
        multiActiveArray: MultiActiveArrayService;
    };
}
export interface UiSchemaContext {
    isAdmin?: boolean;
    isEdit?: boolean;
    creator?: string;
    confirmDelete?: boolean;
    additionalClassNames?: Record<string, string>;
    [key: string]: any;
}
export type NotifyMessager = (msg: string) => void;
export interface Notifier {
    success: NotifyMessager;
    info: NotifyMessager;
    warning: NotifyMessager;
    error: NotifyMessager;
}
export type ByLang = {
    [key: string]: string;
};
export type Translations = Record<Lang, ByLang>;
export default class LajiForm extends React.Component<LajiFormProps, LajiFormState> {
    static contextType: React.Context<ContextProps>;
    private contextMemoizeKey;
    private contextFormMemoizeKey;
    memoizedContext: ContextProps;
    memoizedFormContext: FormContext;
    translations: Translations;
    bgJobRef: React.RefObject<FailedBackgroundJobsPanel>;
    shortcutHelpRef: React.RefObject<any>;
    apiClient: ApiClient;
    _id: number;
    propagateSubmit: boolean;
    formRef: React.RefObject<Form<any, import("@rjsf/utils").RJSFSchema, any>>;
    mounted: boolean;
    keyCombo: string;
    defaultNotifier: Notifier;
    validating: boolean;
    cachedNonliveValidations: any;
    helpVisible: boolean;
    helpTimeout: number;
    helpStarted: boolean;
    eventListeners: [typeof document | typeof window, string, (e: Event) => void][];
    timeouts: number[];
    static propTypes: {
        uiSchemaContext: PropTypes.Requireable<object>;
        settings: PropTypes.Requireable<object>;
        validators: PropTypes.Requireable<object>;
        warnings: PropTypes.Requireable<object>;
    };
    static defaultProps: {
        lang: Lang;
        schema: {};
        uiSchema: {};
    };
    constructor(props: LajiFormProps);
    UNSAFE_componentWillReceiveProps(props: LajiFormProps): void;
    getStateFromProps(props: LajiFormProps): LajiFormState;
    getMemoizedFormContext(props: LajiFormProps): FormContext;
    componentDidMount(): void;
    componentWillUnmount(): void;
    componentDidCatch(e: Error, i: React.ErrorInfo): void;
    componentDidUpdate(prevProps: LajiFormProps): void;
    onSubmitHooksChange: (submitHooks: SubmitHook[], callback?: () => void) => void;
    resetShortcuts(shortcuts?: ShortcutKeys): void;
    constructTranslations(): Translations;
    getDefaultNotifier: () => Notifier;
    onChange: ({ formData }: {
        formData: any;
    }) => void;
    getFields: (_fields?: {
        [name: string]: Field;
    }) => {
        SchemaField: typeof fields.SchemaField;
        ArrayField: typeof fields.ArrayField;
        ObjectField: (props: any) => JSX.Element;
        NestField: typeof fields.NestField;
        ArrayPropertySumField: typeof fields.ArrayPropertySumField;
        ArrayPropertyCountField: typeof fields.ArrayPropertyCountField;
        ScopeField: typeof fields.ScopeField;
        SelectTreeField: typeof fields.SelectTreeField;
        GridLayoutField: {
            (props: any): JSX.Element;
            propTypes: {
                uiSchema: PropTypes.Requireable<PropTypes.InferProps<{
                    "ui:grid": PropTypes.Requireable<PropTypes.InferProps<{
                        lg: PropTypes.Requireable<NonNullable<number | object | null | undefined>>;
                        md: PropTypes.Requireable<NonNullable<number | object | null | undefined>>;
                        sm: PropTypes.Requireable<NonNullable<number | object | null | undefined>>;
                        xs: PropTypes.Requireable<NonNullable<number | object | null | undefined>>;
                    }>>;
                }>>;
                schema: PropTypes.Validator<NonNullable<PropTypes.InferProps<{
                    type: PropTypes.Requireable<string>;
                }>>>;
            };
        };
        TableField: typeof fields.TableField;
        InjectField: typeof fields.InjectField;
        InjectDefaultValueField: typeof fields.InjectDefaultValueField;
        ArrayCombinerField: typeof fields.ArrayCombinerField;
        DependentBooleanField: typeof fields.DependentBooleanField;
        DependentDisableField: typeof fields.DependentDisableField;
        MapArrayField: typeof fields.MapArrayField;
        AutoArrayField: typeof fields.AutoArrayField;
        AutosuggestField: typeof fields.AutosuggestField;
        HiddenField: {
            (): JSX.Element;
            propTypes: {
                schema: PropTypes.Validator<NonNullable<PropTypes.InferProps<{
                    type: PropTypes.Requireable<string>;
                }>>>;
            };
        };
        HiddenWithTextField: {
            (props: FieldProps<import("../types").JSONSchemaArray<import("../types").JSONSchemaString>>): JSX.Element;
            propTypes: {
                uiSchema: PropTypes.Validator<NonNullable<PropTypes.InferProps<{
                    "ui:options": PropTypes.Validator<NonNullable<PropTypes.InferProps<{
                        altText: PropTypes.Validator<string>;
                    }>>>;
                    uiSchema: PropTypes.Requireable<object>;
                }>>>;
                schema: PropTypes.Validator<NonNullable<PropTypes.InferProps<{
                    type: PropTypes.Requireable<string>;
                }>>>;
            };
        };
        InitiallyHiddenField: typeof fields.InitiallyHiddenField;
        ContextInjectionField: typeof fields.ContextInjectionField;
        ImageArrayField: typeof fields.ImageArrayField;
        SplitField: typeof fields.SplitField;
        FlatField: typeof fields.FlatField;
        SingleActiveArrayField: typeof fields.SingleActiveArrayField;
        SingleItemArrayField: typeof fields.SingleItemArrayField;
        UnitShorthandField: typeof fields.UnitShorthandField;
        CombinedValueDisplayField: typeof fields.CombinedValueDisplayField;
        UiFieldMapperArrayField: typeof fields.UiFieldMapperArrayField;
        ExtraLabelRowField: typeof fields.ExtraLabelRowField;
        SumField: typeof fields.SumField;
        NamedPlaceChooserField: typeof fields.NamedPlaceChooserField;
        NamedPlaceSaverField: typeof fields.NamedPlaceSaverField;
        MapField: typeof fields.MapField;
        GeocoderField: typeof fields.GeocoderField;
        TagArrayField: typeof fields.TagArrayField;
        StringToArrayField: typeof fields.StringToArrayField;
        ConditionalOnChangeField: typeof fields.ConditionalOnChangeField;
        ConditionalUiSchemaField: typeof fields.ConditionalUiSchemaField;
        AnnotationField: typeof fields.AnnotationField;
        PrefillingArrayField: typeof fields.PrefillingArrayField;
        AnyToBooleanField: {
            (props: FieldProps): JSX.Element;
            propTypes: {
                uiSchema: PropTypes.Requireable<PropTypes.InferProps<{
                    "ui:options": PropTypes.Requireable<PropTypes.InferProps<{
                        trueValue: PropTypes.Validator<object>;
                        falseValue: PropTypes.Requireable<object>;
                        allowUndefined: PropTypes.Requireable<boolean>;
                    }>>;
                }>>;
                schema: PropTypes.Validator<NonNullable<PropTypes.InferProps<{
                    type: PropTypes.Requireable<string>;
                }>>>;
                formData: PropTypes.Requireable<object>;
            };
        };
        EnumRangeArrayField: typeof fields.EnumRangeArrayField;
        UnitListShorthandArrayField: typeof fields.UnitListShorthandArrayField;
        LocationChooserField: typeof fields.LocationChooserField;
        DataLeakerField: typeof fields.DataLeakerField;
        LocalityField: typeof fields.LocalityField;
        ImageDisplayField: typeof fields.ImageDisplayField;
        FakePropertyField: typeof fields.FakePropertyField;
        SectionArrayField: typeof fields.SectionArrayField;
        MultiArrayField: typeof fields.MultiArrayField;
        AudioArrayField: typeof fields.AudioArrayField;
        FilterArrayField: typeof fields.FilterArrayField;
        MultiAnyToBooleanField: typeof fields.MultiAnyToBooleanField;
        UnitCountShorthandField: typeof fields.UnitCountShorthandField;
        ToggleAdditionalArrayFieldsField: typeof fields.ToggleAdditionalArrayFieldsField;
        DefaultValueArrayField: typeof fields.DefaultValueArrayField;
        UiFieldApplierField: typeof fields.UiFieldApplierField;
        MultiLanguageField: typeof fields.MultiLanguageField;
        SortArrayField: typeof fields.SortArrayField;
        InputWithDefaultValueButtonField: typeof fields.InputWithDefaultValueButtonField;
        MultiTagArrayField: typeof fields.MultiTagArrayField;
        PdfArrayField: typeof fields.PdfArrayField;
        AsArrayField: typeof fields.AsArrayField;
        CondensedObjectField: typeof fields.CondensedObjectField;
        MultiActiveArrayField: typeof fields.MultiActiveArrayField;
        PrefixArrayField: typeof fields.PrefixArrayField;
        FillDateRangeField: typeof fields.FillDateRangeField;
        TaxaByYearPopulatorField: typeof fields.TaxaByYearPopulatorField;
        TaxonSetPopulatorField: typeof fields.TaxonSetPopulatorField;
        ScientificNameTaxonAutosuggestField: typeof fields.ScientificNameTaxonAutosuggestField;
        ArraySchemaField: typeof fields.SchemaField;
        InputTransformerField: typeof fields.ConditionalOnChangeField;
        ConditionalField: typeof fields.ConditionalUiSchemaField;
        UnitRapidField: typeof fields.UnitShorthandField;
        AccordionArrayField: typeof fields.SingleActiveArrayField;
    };
    getWidgets: (_widgets?: {
        [name: string]: Widget;
    }) => {
        CheckboxWidget: typeof widgets.CheckboxWidget;
        SelectWidget: <T extends string | number>(props: (Omit<import("../types").WidgetProps<import("../types").JSONSchemaEnum>, "value" | "onChange"> & {
            value?: T | undefined;
            onChange: (value?: T | undefined) => void;
        } & {
            includeEmpty?: boolean;
            getEnumOptionsAsync?: (() => Promise<(Omit<import("@rjsf/utils").EnumOptionsType, "value"> & {
                value: T;
            })[]>) | undefined;
        }) | (Omit<import("../types").WidgetProps<import("../types").JSONSchemaArray<import("../types").JSONSchemaEnumOneOf>>, "value" | "onChange"> & {
            value?: T[] | undefined;
            onChange: (value?: T[] | undefined) => void;
        } & {
            includeEmpty?: boolean;
            getEnumOptionsAsync?: (() => Promise<(Omit<import("@rjsf/utils").EnumOptionsType, "value"> & {
                value: T;
            })[]>) | undefined;
        })) => JSX.Element;
        TextareaWidget: typeof widgets.TextareaWidget;
        DateTimeWidget: typeof widgets.DateTimeWidget;
        DateWidget: {
            (props: any): JSX.Element;
            propTypes: {
                uiSchema: PropTypes.Requireable<PropTypes.InferProps<{
                    "ui:options": PropTypes.Requireable<PropTypes.InferProps<{
                        showButtons: PropTypes.Requireable<NonNullable<boolean | PropTypes.InferProps<{
                            today: PropTypes.Requireable<boolean>;
                            yesterday: PropTypes.Requireable<boolean>;
                            same: PropTypes.Requireable<NonNullable<boolean | PropTypes.InferProps<{
                                path: PropTypes.Requireable<string>;
                            }> | null | undefined>>;
                            plusSixMonths: PropTypes.Requireable<NonNullable<boolean | PropTypes.InferProps<{
                                path: PropTypes.Requireable<string>;
                            }> | null | undefined>>;
                            plusSixYear: PropTypes.Requireable<NonNullable<boolean | PropTypes.InferProps<{
                                path: PropTypes.Requireable<string>;
                            }> | null | undefined>>;
                        }> | null | undefined>>;
                        allowOnlyYear: PropTypes.Requireable<boolean>;
                    }>>;
                }>>;
                schema: PropTypes.Requireable<PropTypes.InferProps<{
                    type: PropTypes.Requireable<string>;
                }>>;
                value: PropTypes.Requireable<string>;
            };
        };
        TimeWidget: {
            (props: any): JSX.Element;
            propTypes: {
                schema: PropTypes.Requireable<PropTypes.InferProps<{
                    type: PropTypes.Requireable<string>;
                }>>;
                value: PropTypes.Requireable<string>;
            };
        };
        SeparatedDateTimeWidget: typeof widgets.SeparatedDateTimeWidget;
        AutosuggestWidget: typeof widgets.AutosuggestWidget;
        HiddenWidget: typeof widgets.HiddenWidget;
        PlainTextWidget: typeof widgets.PlainTextWidget;
        TextSelectWidget: typeof widgets.TextSelectWidget;
        ImageSelectWidget: typeof widgets.ImageSelectWidget;
        AnyToBooleanWidget: {
            (props: import("../types").WidgetProps): JSX.Element;
            propTypes: {
                uiSchema: PropTypes.Requireable<PropTypes.InferProps<{
                    "ui:options": PropTypes.Requireable<PropTypes.InferProps<{
                        trueValue: PropTypes.Validator<NonNullable<NonNullable<string | number | boolean | null | undefined>>>;
                        falseValue: PropTypes.Requireable<NonNullable<string | number | boolean | null | undefined>>;
                        allowUndefined: PropTypes.Requireable<boolean>;
                    }>>;
                }>>;
                schema: PropTypes.Validator<NonNullable<PropTypes.InferProps<{
                    type: PropTypes.Requireable<string>;
                }>>>;
                formData: PropTypes.Requireable<NonNullable<string | number | boolean | null | undefined>>;
            };
        };
        URLWidget: {
            ({ value, options }: {
                value: any;
                options?: {} | undefined;
            }): JSX.Element;
            propTypes: {
                schema: PropTypes.Requireable<PropTypes.InferProps<{
                    type: PropTypes.Requireable<string>;
                }>>;
                value: PropTypes.Requireable<string>;
            };
        };
        InformalTaxonGroupChooserWidget: typeof widgets.InformalTaxonGroupChooserWidget;
        TaxonImageWidget: typeof widgets.TaxonImageWidget;
        UpperCaseWidget: typeof widgets.UpperCaseWidget;
        NumberWidget: typeof widgets.NumberWidget;
        InputGroupWidget: typeof widgets.InputGroupWidget;
        InputWithDefaultValueButtonWidget: typeof widgets.InputWithDefaultValueButtonWidget;
    };
    getTemplates: (_templates?: {
        [name: string]: TemplatesType;
    }) => {
        BaseInputTemplate: typeof templates.BaseInputTemplate;
        DescriptionField: typeof templates.DescriptionField;
        FieldTemplate: typeof templates.FieldTemplate;
        ArrayFieldTemplate: {
            new (): {
                [x: string]: any;
                componentDidMount(): void;
                componentDidUpdate(prevProps: any, prevState: any): void;
                componentWillUnmount(): void;
                addKeyHandlers(): void;
                arrayKeyFunctions: any;
                removeKeyHandlers(props: any): void;
                getKeyHandlers(props: any): any[];
                addChildKeyHandlers(props: any): void;
                childKeyHandlers: any;
                removeChildKeyHandlers(): void;
                getChildKeyHandlers(props: any): any;
                onFocus: (target: any) => void;
                onCopy: (options?: {}) => void;
                getCustomEventListeners(): (string | ((target: any) => void))[][];
                addCustomEventListeners(props: any): void;
                customEventListeners: any;
                removeCustomEventListeners(props: any): void;
            };
            [x: string]: any;
            displayName: string;
        };
        ErrorListTemplate: typeof templates.ErrorListTemplate;
        ObjectFieldTemplate: typeof templates.ObjectFieldTemplate;
        TitleFieldTemplate: (props: any) => JSX.Element | null;
        DescriptionFieldTemplate: typeof templates.DescriptionField;
    };
    getContext: (props: LajiFormProps, context: ContextProps) => ContextProps;
    render(): JSX.Element | null;
    renderSubmitHooks: () => JSX.Element | null | undefined;
    validateAndSubmit: (warnings?: boolean, onlySchema?: boolean) => Promise<void>;
    validate: (warnings?: boolean, nonlive?: boolean, onlySchema?: boolean) => Promise<unknown>;
    onSubmit: (onlySchemaValidations?: "onlySchemaValidations") => false | undefined;
    popErrorListIfNeeded: () => void;
    _onDefaultSubmit: (e: React.SyntheticEvent) => void;
    submit: () => void;
    submitOnlySchemaValidations: () => void;
    getShorcutButtonTooltip: () => string | undefined;
    toggleHelp: (e: React.MouseEvent) => void;
    showHelp: () => void;
    dismissHelp: (e: Event | React.SyntheticEvent) => void;
    keyFunctions: {
        navigate: (e: KeyboardEvent, { reverse }: any) => void;
        help: (e: KeyboardEvent, { delay }: any) => boolean;
        revalidate: () => void;
    };
    pushBlockingLoader: () => void;
    popBlockingLoader: () => void;
    focusField: (fieldName: string) => void;
    openAllMultiActiveArrays: () => void;
    closeAllMultiActiveArrays: () => void;
    getSettings(): {
        [x: string]: any;
    };
    onSettingsChange: (settings: Settings) => void;
    addEventListener: (target: typeof document | typeof window, name: string, fn: (e: Event) => void) => void;
    setTimeout: (fn: () => void, time?: number) => number;
    destroy: () => void;
    getSchemaValidationErrors: (formData: any) => any;
    getFormDataReadyForSubmit: (formData: any, schema: JSONSchema) => {
        formData: any;
        removedArrayItemsAndObjects: string[];
    };
}
