import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
import { forwardRef, useEffect, useImperativeHandle, useMemo, } from "react";
import { FormMode, } from "./Form.types";
import { useFieldErrors, useFormAnswers, useFormState, } from "./Form.hook";
import FormField from "./FormField";
import { useOneUIConfig } from "../../context/OneUIProvider";
function Form({ questions, initialAnswers = {}, ...props }, ref) {
    const filterOutInitialAnswers = useMemo(() => {
        const questionIds = questions.map((a) => a.id);
        return Object.fromEntries(Object.entries(initialAnswers).filter(([id]) => questionIds.includes(id)));
    }, [initialAnswers]);
    const answers = useFormAnswers(filterOutInitialAnswers, props.mode);
    return (_jsx(ControlledForm, { ref: ref, questions: questions, initialAnswers: initialAnswers, answers: answers, ...props }));
}
const forwardedRef = forwardRef(Form);
/**
 * A new and improved version of the one-ui design form
 *
 * Custom question types can be defined via @type {OnepercentUtility['UIElements']['FormExtension']['fields']}
 *
 * This component displays a form with multiple questions and allows users
 * to enter answers to those questions. It handles validation, different
 * display modes, and manages the form's state.
 **/
export default forwardedRef;
function ControlledFormComp({ questions, initialAnswers = {}, answers: answersControl, ...props }, ref) {
    const { mode = FormMode.WRITE } = props;
    const { showAllErrors = false } = props;
    const { answers, onAnswerAction, isQuestionsAnswered, isFilesUploaded } = useFormState(questions, answersControl);
    const errors = useFieldErrors(questions, answersControl.answers, showAllErrors);
    const answersArray = useMemo(() => {
        return questions.map((q) => answersControl.answers[q.id]);
    }, [questions.map((a) => a.id), answersControl.answers]);
    useEffect(() => {
        if (props.mode !== FormMode.READ_ONLY) {
            props.onFormUpdate(answers, isQuestionsAnswered && isFilesUploaded);
        }
    }, [...answersArray, isQuestionsAnswered, isFilesUploaded]);
    useImperativeHandle(ref, () => ({
        setAnswer(id, val) {
            onAnswerAction(questions.find((q) => q.id === id).type, id, val);
        },
    }), []);
    const wrapperClasses = useOneUIConfig("component.form.fieldWrapper", {});
    return (_jsx(_Fragment, { children: questions.map((q) => {
            const targetMode = q.readOnly ? FormMode.READ_ONLY : mode;
            const classOrComponentWrapper = wrapperClasses[`${FormMode[targetMode]}-${q.type}`];
            const WrapperComp = useMemo(() => typeof classOrComponentWrapper === "function"
                ? classOrComponentWrapper
                : ({ children }) => {
                    return (_jsx("div", { className: `${classOrComponentWrapper || ""}`, children: children }, q.id));
                }, [classOrComponentWrapper]);
            return (_jsx(WrapperComp, { ...q, value: answersControl.answers[q.id], children: targetMode === FormMode.WRITE ? (_jsx(FormField, { config: q, onAnswer: onAnswerAction, value: answersControl.answers[q.id], error: errors[q.id], mode: targetMode, "data-testid": props["data-testid"]?.(q.id) })) : (_jsx(FormField, { config: q, value: answersControl.answers[q.id], mode: FormMode.READ_ONLY, "data-testid": props["data-testid"]?.(q.id) })) }));
        }) }));
}
export const ControlledForm = forwardRef(ControlledFormComp);
//# sourceMappingURL=Form.js.map