import * as React from "react";
import {HashMap} from "../../typings/common";
import {FormErrorAutoFocusContainer} from "./FormErrorAutoFocusContainer";

type InputConverter = () => any;
type OutputConverter = () => any;

type Props = {
    onChange?: Function,
    name?: string,
    inputConverter?: InputConverter,
    outputConverter?: OutputConverter,
    noContainer?: boolean,
    testAutomationId?: string,
    children: React.ReactNode,
    disableAutoFocus?: boolean
    className?: string,
} & Partial<DefaultProps> & Partial<FormContext['form']>;

type DefaultProps = {
    // onChange: null,
    name: string,
    inputConverter: null,
    outputConverter: null,
    testAutomationId: string,
    noContainer: boolean,
    disableAutoFocus: boolean
}

type FormValue = HashMap<any>;

export type FormContext = {
    form: {
        readOnly: boolean,
        value: FormValue,
        errors: HashMap<string | undefined>;
        setValue: Function;
        autoFocus: Function;
    }
}

export class Form extends React.Component<Props> implements React.ChildContextProvider<FormContext> {
    // static propTypes: object;
    // static defaultProps: object;

    setValue(value: FormValue, diff: Partial<FormValue>): void;

    getInputValue(): any;
    getNeededAutoFocus: FormErrorAutoFocusContainer['getNeededAutoFocus'];
    setOutputValue(value: FormValue, diff: Partial<FormValue>): void;
    setNeededAutoFocus: FormErrorAutoFocusContainer['setNeededAutoFocus'];

    getChildContext(): FormContext;
    inputConverter(value: FormValue): FormValue | ReturnType<InputConverter>;
    outputConverter(value: FormValue, diff: Partial<FormValue>): FormValue | ReturnType<OutputConverter>;
    extractProperty(propName: string, props: Props): any;
    extractFlatProperty(propName: string): any;
}