import * as __WEBPACK_EXTERNAL_MODULE_react__ from "react";
import * as __WEBPACK_EXTERNAL_MODULE__chakra_ui_react__ from "@chakra-ui/react";
import * as __WEBPACK_EXTERNAL_MODULE_react_hook_form__ from "react-hook-form";
import * as __WEBPACK_EXTERNAL_MODULE__hookform_devtools__ from "@hookform/devtools";
import * as __WEBPACK_EXTERNAL_MODULE__hookform_resolvers_yup__ from "@hookform/resolvers/yup";
import * as __WEBPACK_EXTERNAL_MODULE_yup__ from "yup";
import * as __WEBPACK_EXTERNAL_MODULE__hooks_useReactHookForm_mjs__ from "../../hooks/useReactHookForm.mjs";
import * as __WEBPACK_EXTERNAL_MODULE__FormField_FormField_mjs__ from "../FormField/FormField.mjs";
import * as __WEBPACK_EXTERNAL_MODULE__Inputs_NumberInput_NumberInput_mjs__ from "../Inputs/NumberInput/NumberInput.mjs";
import * as __WEBPACK_EXTERNAL_MODULE__Inputs_RadioGroup_RadioGroup_mjs__ from "../Inputs/RadioGroup/RadioGroup.mjs";
import * as __WEBPACK_EXTERNAL_MODULE__Inputs_Select_Select_mjs__ from "../Inputs/Select/Select.mjs";
import * as __WEBPACK_EXTERNAL_MODULE__Inputs_Slider_RPSlider_mjs__ from "../Inputs/Slider/RPSlider.mjs";
import * as __WEBPACK_EXTERNAL_MODULE__Inputs_ColumnSelect_ColumnSelect_mjs__ from "../Inputs/ColumnSelect/ColumnSelect.mjs";
import * as __WEBPACK_EXTERNAL_MODULE__Button_Button_mjs__ from "../Button/Button.mjs";
import * as __WEBPACK_EXTERNAL_MODULE__Inputs_PasswordInput_PasswordInput_mjs__ from "../Inputs/PasswordInput/PasswordInput.mjs";
// Create an array of objects, based on the provided CustomFields, later used
// to transform into Yup validation schema.
// Note: This function is recursive to support nested fields, such as those
// in a `CustomFormSection`.
//
// Previously, with tuples, it made it difficult to flatten the array, (since
// TS tuples are really just arrays. Instead, we now use objects to better flatten
// the array and then map over those objects to create the schema.
function generateValidationSchemaObject(fields) {
    let schema = fields.filter((field)=>'displaySection' !== field.fieldType).map((field)=>{
        if ('custom' === field.fieldType && 'fields' in field) return generateValidationSchemaObject(field.fields);
        return {
            name: field.name,
            schema: field.schema
        };
    });
    return schema.flat();
}
// Create an array of initial/default values for Yup based on the provided
// CustomFields.
// Note: This function is recursive to support nested fields, such as those
// in a `CustomFormSection`.
function generateInitialValuesObject(fields) {
    const initialValues = fields.filter((field)=>'displaySection' !== field.fieldType).map((field)=>{
        if ('custom' === field.fieldType && 'fields' in field) return generateInitialValuesObject(field.fields);
        if ('select' !== field.fieldType || !field.defaultValue) return {
            name: field.name,
            defaultValue: field.defaultValue
        };
        {
            const selectField = field;
            return {
                name: selectField.name,
                defaultValue: selectField.isMulti ? selectField.defaultValue : selectField.defaultValue.value
            };
        }
    });
    return initialValues.flat();
}
function Form({ onValid, onInvalid, fields, button, autofocus, mode, developerView, isDisabled, isFetching, actions, onInvalidFormValidation }) {
    // generate initial schemas (validation and default values)
    const filteredFields = fields.filter((field)=>!field.hide);
    const initialSchemaValues = Object.fromEntries(generateInitialValuesObject(filteredFields).map((fieldObj)=>[
            fieldObj.name,
            fieldObj.defaultValue
        ]));
    const schema = Object.fromEntries(generateValidationSchemaObject(filteredFields).map((fieldObj)=>[
            fieldObj.name,
            fieldObj.schema
        ]));
    const validationSchema = __WEBPACK_EXTERNAL_MODULE_yup__.object().shape(schema);
    // used for custom form sections so the validation context can be passed to
    // custom validators for that section
    const [validationContext, setValidationContext] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)({});
    // Focus
    const inputRef = (0, __WEBPACK_EXTERNAL_MODULE_react__.useRef)();
    (0, __WEBPACK_EXTERNAL_MODULE_react__.useEffect)(()=>{
        if (autofocus && inputRef) inputRef.current?.focus();
    }, [
        inputRef,
        autofocus
    ]);
    const { formValues, setFormMethods } = (0, __WEBPACK_EXTERNAL_MODULE__hooks_useReactHookForm_mjs__["default"])();
    const defaultValues = formValues && Object.entries(formValues).length > 0 ? {
        ...initialSchemaValues,
        ...formValues
    } : initialSchemaValues;
    // Form management
    const formMethods = (0, __WEBPACK_EXTERNAL_MODULE_react_hook_form__.useForm)({
        mode: mode || 'all',
        defaultValues,
        resolver: (0, __WEBPACK_EXTERNAL_MODULE__hookform_resolvers_yup__.yupResolver)(validationSchema),
        context: validationContext
    });
    (0, __WEBPACK_EXTERNAL_MODULE_react__.useEffect)(()=>{
        setFormMethods(formMethods);
    }, []);
    const { register, handleSubmit, setValue, control, formState: { isSubmitting, errors } } = formMethods;
    const isFormDisabled = isSubmitting || isDisabled || isFetching;
    const isFormSubmissionDisabled = isFormDisabled || Object.keys(errors).length > 0;
    (0, __WEBPACK_EXTERNAL_MODULE_react__.useEffect)(()=>{
        if (isFormSubmissionDisabled && void 0 !== onInvalidFormValidation) onInvalidFormValidation();
    }, [
        isFormSubmissionDisabled
    ]);
    const allActions = /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE_react__["default"].Fragment, null, /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__Button_Button_mjs__["default"], {
        variant: button.variant ?? 'brand',
        "aria-label": button.label,
        "data-testid": button.label,
        type: "submit",
        isLoading: isSubmitting || isFetching,
        isDisabled: isFormSubmissionDisabled
    }, button.text), actions);
    const mapFields = (fields)=>{
        const mappedFields = fields.map(({ label, columns, help, description, footerDescription, tooltip, heading, showRequiredIndicator, ...field })=>{
            if ('displaySection' === field.fieldType) return /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.Box, {
                key: field.name
            }, heading && /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.Heading, {
                as: "h5",
                size: "md"
            }, heading), description && /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.Text, null, description));
            // TODO: expand repeater to build out form structure in an automated
            // way similar to the other form fields
            if ('repeater' === field.fieldType) return /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE_react__["default"].Fragment, null);
            if ('custom' === field.fieldType) {
                let f = field;
                return /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(f.component, {
                    form: formMethods,
                    setValidationContext: setValidationContext,
                    key: field.name
                });
            }
            return /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE_react__.Fragment, {
                key: field.name
            }, /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__FormField_FormField_mjs__["default"], {
                description: description,
                footerDescription: footerDescription,
                tooltip: tooltip,
                isRequired: 'hidden' !== field.fieldType && false !== field.isRequired,
                isDisabled: field.isDisabled || isFormDisabled,
                key: field.name,
                hidden: 'hidden' === field.fieldType,
                style: columns && {
                    gridColumn: `span ${columns}`
                },
                label: label,
                isInvalid: !!errors[field.name],
                errorText: errors[field.name]?.message,
                helpText: help,
                showRequiredIndicator: showRequiredIndicator
            }, {
                text: /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.Input, {
                    "data-testid": `${field.name}_field`,
                    placeholder: field.placeholder,
                    pattern: field.pattern,
                    type: field.inputMode,
                    ...register(field.name)
                }),
                password: /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE_react_hook_form__.Controller, {
                    name: field.name,
                    control: control,
                    render: ({ field: renderField })=>{
                        /**
                         * Ref has to be excluded due to a limitation of the components
                         * Chakra implementation is using function components where ref cannot be provided
                         */ const { ref, ...rest } = renderField;
                        const passwordField = field;
                        return /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__Inputs_PasswordInput_PasswordInput_mjs__["default"], {
                            ...rest,
                            name: passwordField.name,
                            placeholder: passwordField.placeholder,
                            pattern: passwordField.pattern,
                            type: passwordField.inputMode,
                            defaultShowPassword: passwordField.defaultShowPassword,
                            showEyeIndicator: passwordField.showEyeIndicator
                        });
                    }
                }),
                toggle: /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE_react_hook_form__.Controller, {
                    name: field.name,
                    control: control,
                    render: ({ field: renderField })=>{
                        const toggleField = field;
                        return /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.Box, {
                            "data-testid": `${toggleField.name}_field`
                        }, /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.Switch, {
                            ...renderField,
                            defaultChecked: 'true' === toggleField.defaultValue
                        }));
                    }
                }),
                hidden: /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.Input, {
                    "data-testid": `${field.name}_field`,
                    hidden: true,
                    type: "none",
                    ...register(field.name)
                }),
                number: /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE_react_hook_form__.Controller, {
                    name: field.name,
                    control: control,
                    render: ({ field: renderField })=>{
                        /**
                         * Ref has to be excluded due to a limitation of the components
                         * Chakra implementation is using function components where ref cannot be provided
                         */ const { ref, ...rest } = renderField;
                        const numberField = field;
                        return /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__Inputs_NumberInput_NumberInput_mjs__["default"], {
                            ...rest,
                            name: numberField.name,
                            min: numberField.min,
                            max: numberField.max,
                            step: numberField.step,
                            placeholder: numberField.placeholder
                        });
                    }
                }),
                radio: /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE_react_hook_form__.Controller, {
                    name: field.name,
                    control: control,
                    render: ({ field: renderField })=>{
                        const { ref, ...rest } = renderField;
                        const radioField = field;
                        if ('circle' === radioField.radioVariant) return /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.Box, {
                            "data-testid": `${field.name}_field`,
                            mt: 2
                        }, /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.RadioGroup, {
                            ...rest,
                            defaultValue: field.defaultValue,
                            onChange: (nextValue)=>{
                                setValue(radioField.name, nextValue);
                                setFormMethods(formMethods);
                            }
                        }, /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.Stack, {
                            direction: radioField.radioStackDirection
                        }, radioField.options.map(({ label, value, disabled, invalid, ...otherOptionProps })=>/*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.Radio, {
                                key: `${value}`,
                                value: `${value}`,
                                isDisabled: disabled,
                                isInvalid: invalid,
                                ...otherOptionProps
                            }, /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.Text, {
                                "aria-invalid": invalid,
                                _invalid: {
                                    textColor: 'red.500',
                                    borderColor: 'red.500'
                                }
                            }, label))))));
                        return /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.Box, {
                            "data-testid": `${field.name}_field`
                        }, /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__Inputs_RadioGroup_RadioGroup_mjs__["default"], {
                            ...rest,
                            isAttached: radioField.isAttached,
                            options: radioField.options || [],
                            defaultValue: radioField.defaultValue,
                            onChange: (nextValue)=>{
                                setValue(radioField.name, nextValue);
                                setFormMethods(formMethods);
                            }
                        }));
                    }
                }),
                select: /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE_react_hook_form__.Controller, {
                    name: field.name,
                    control: control,
                    render: ({ field: renderField })=>{
                        const { ref, ...rest } = renderField;
                        const selectField = field;
                        return /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.Box, {
                            "data-testid": `${selectField.name}_field`
                        }, /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__Inputs_Select_Select_mjs__["default"], {
                            menuPlacement: "auto",
                            ...rest,
                            innerRef: selectField.innerRef,
                            placeholder: selectField.placeholder,
                            isLoading: selectField.isLoading,
                            isMulti: selectField.isMulti,
                            options: selectField.options,
                            defaultValue: selectField.defaultValue,
                            onChange: (nextValue)=>{
                                setValue(selectField.name, nextValue);
                                setFormMethods(formMethods);
                            }
                        }));
                    }
                }),
                columnSelect: /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE_react_hook_form__.Controller, {
                    name: field.name,
                    control: control,
                    render: ({ field: renderField })=>{
                        const { ref, ...rest } = renderField;
                        const columnSelectField = field;
                        return /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.Box, {
                            "data-testid": `${columnSelectField.name}_field`
                        }, /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__Inputs_ColumnSelect_ColumnSelect_mjs__["default"], {
                            menuPlacement: "auto",
                            ...rest,
                            innerRef: columnSelectField.innerRef,
                            placeholder: columnSelectField.placeholder,
                            isLoading: columnSelectField.isLoading,
                            options: columnSelectField.options,
                            defaultValue: columnSelectField.defaultValue,
                            firstTextPosition: columnSelectField.firstTextPosition,
                            headerColumns: columnSelectField.headerColumns,
                            footer: columnSelectField.footer,
                            singleValueText: columnSelectField.singleValueText,
                            onChange: (nextValue)=>{
                                setValue(columnSelectField.name, nextValue);
                                setFormMethods(formMethods);
                            }
                        }));
                    }
                }),
                textarea: /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.Textarea, {
                    ...register(field.name),
                    "data-testid": `${field.name}_field`,
                    placeholder: field.placeholder
                }),
                slider: /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE_react_hook_form__.Controller, {
                    name: field.name,
                    control: control,
                    render: ({ field: renderField })=>{
                        const { ref, ...rest } = renderField;
                        const sliderField = field;
                        const { fieldType, ...sliderRest } = sliderField;
                        return /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.Box, {
                            "data-testid": `${sliderField.name}_field`
                        }, /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__Inputs_Slider_RPSlider_mjs__["default"], {
                            ...sliderRest,
                            ...rest,
                            onChange: (nextValue)=>{
                                setValue(sliderField.name, nextValue);
                                setFormMethods(formMethods);
                            }
                        }));
                    }
                }),
                displaySection: /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE_react__["default"].Fragment, null),
                checkbox: /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE_react_hook_form__.Controller, {
                    name: field.name,
                    control: control,
                    render: ({ field: renderField })=>{
                        const checkboxField = field;
                        return /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.Box, {
                            "data-testid": `${checkboxField.name}_field`
                        }, /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.Checkbox, renderField, checkboxField.text));
                    }
                })
            }[field.fieldType || 'text']));
        });
        return mappedFields.flat();
    };
    return /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE_react__["default"].Fragment, null, /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.chakra.form, {
        onChange: ()=>setFormMethods(formMethods),
        onSubmit: handleSubmit(onValid, onInvalid)
    }, /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.chakra.fieldset, null, /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.VStack, {
        alignItems: "left",
        gap: 6
    }, mapFields(fields), button.spanFullWidth ? allActions : /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.Box, null, /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__chakra_ui_react__.ButtonGroup, null, allActions))))), developerView ? /*#__PURE__*/ __WEBPACK_EXTERNAL_MODULE_react__["default"].createElement(__WEBPACK_EXTERNAL_MODULE__hookform_devtools__.DevTool, {
        control: control
    }) : null);
}
/* ESM default export */ const Form_rslib_entry_ = Form;
export { Form_rslib_entry_ as default };
