import React, {createContext, useContext, useMemo, useRef} from 'react';

interface FormProps {
    onSubmit: () => void;
    children: React.ReactNode;
}

interface FormManager {
    registerValidator: (v: () => boolean) => void;
    deregisterValidator: (v: () => boolean) => void;
    submit: () => void;
}

const FormContext = createContext<FormManager | null>(null);
export const useFormContext = () => useContext(FormContext);

export function Form(props: FormProps) {
    const {children, onSubmit} = props;
    const validators = useRef<(() => boolean)[]>([]);
    const v = useMemo(
        () => ({registerValidator, deregisterValidator, submit}),
        [registerValidator, deregisterValidator, submit]
    );

    function registerValidator(validator: () => boolean) {
        validators.current.push(validator);
    };

    function deregisterValidator(validator: () => boolean) {
        validators.current = validators.current.filter((v) => v !== validator);
    };

    function submit() {
        const valid = validators.current.map((v) => v()).reduce((p, v) => p && v);
        if (valid) onSubmit();
    }

    return <FormContext.Provider value={v}>{children}</FormContext.Provider>;
}
