import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { Fragment, useEffect, useState } from "react";
import debounce from "lodash/debounce";
import { FormMode, } from "./FormField.types";
import Select from "../../Select/Select";
import Input from "../../Input";
import OneText from "../../Text";
import Button from "../../Button";
import Radio from "../../Radio";
import { AnchoredTooltipAlignment } from "../../AnchoredTooltip/AnchoredTooltip";
import FileInput from "../../FileInput/FileInput";
import CheckBox from "../../CheckBox/CheckBox";
import Spacing from "../../Spacing";
import { useOneUIConfig } from "../../../context/OneUIProvider";
import AdaptiveContainer from "../../AdaptiveContainer";
import Text from "../../Text";
// import InputMask from "react-input-mask";
/**
 * The logic for a field of the form
 **/
export default function FormField({ config: c, value, ...props }) {
    const variants = useOneUIConfig("component.input.labelVariants", {});
    const val = () => value;
    const ans = (answer) => answer;
    const type = c.type;
    const { titleVariant, labelVariant, optionalLabel, extensions } = useOneUIConfig("component.form");
    if (props.mode === FormMode.READ_ONLY) {
        switch (type) {
            case "check":
                const checks = val() || [];
                return (_jsxs(_Fragment, { children: [_jsx(OneText, { type: titleVariant, children: c.title }), checks.includes(true) ? (checks.map((checked, i) => checked ? (_jsx(OneText, { type: labelVariant, children: c.options[i].value })) : null)) : (_jsx(OneText, { type: labelVariant, children: "-" })), _jsx(Spacing, { size: "small" })] }));
            case "file":
                const file = val();
                return (_jsxs(_Fragment, { children: [_jsx(FileInput, { states: {
                                fileProvided: {
                                    title: c.title,
                                    description: c.fileUsageDescription,
                                },
                                waitingFile: {
                                    title: c.title,
                                    description: c.fileUsageDescription,
                                },
                            }, footer: c.footer, onFile: () => { }, file: file === true ? {} : undefined, progress: file === true ? 100 : undefined, disabled: true }), _jsx(Spacing, { size: "small" }), file === true && (_jsx(Button, { variant: "link", color: "primary", onClick: c.openFile.action, children: c.openFile.label })), _jsx(Spacing, { size: "large" })] }));
            default:
                const CustomReadOnly = extensions?.[type]
                    ?.ReadOnly;
                const answer = val();
                if (!CustomReadOnly && typeof answer === "object")
                    throw new Error(`There is no custom read only component for the form field type "${type}". Please review and set it at OneUIProvider.`);
                return (_jsxs(_Fragment, { children: [_jsx(OneText, { type: titleVariant, children: c.title }), _jsx(OneText, { type: labelVariant, "data-testid": props["data-testid"], children: CustomReadOnly ? (_jsx(CustomReadOnly, { question: c, value: value, "data-testid": props["data-testid"] })) : (answer || "-") })] }));
        }
    }
    const { onAnswer, error } = props;
    switch (type) {
        case "accept":
            const checks = val() || [];
            return (_jsxs(_Fragment, { children: [_jsxs("div", { children: [_jsxs("div", { children: [_jsx(OneText, { type: titleVariant, children: c.title }), _jsx("br", {}), _jsx(Button, { variant: "link", color: "primary", onClick: c.contract.action, children: c.contract.label })] }), error && (_jsxs("div", { children: [_jsx(OneText, { type: "caption", color: "error", children: error }), _jsx("br", {})] })), _jsx("div", { children: c.accept.map((a, i) => (_jsx(OneText, { type: labelVariant, children: _jsx(CheckBox, { label: _jsx("span", { children: _jsxs(_Fragment, { children: [a.label, a.optional ? (_jsxs(_Fragment, { children: [_jsx("br", {}), _jsx(OneText, { type: "caption", children: optionalLabel })] })) : ("")] }) }), checked: checks[i], onToggle: (checked) => {
                                            const clone = [...checks];
                                            clone[i] = checked;
                                            onAnswer(type, c.id, ans(clone));
                                        }, groupId: c.id, value: a.label }) }))) })] }), _jsx(Spacing, { size: "small" })] }));
        case "file":
            const upload = val();
            const [progress, setProgress] = useState(() => {
                if (!upload)
                    return undefined;
                if (upload === true)
                    return 100;
                const s = upload.snapshot;
                return (s.bytesTransferred * 100) / s.totalBytes;
            });
            useEffect(() => {
                if (!upload)
                    return setProgress(undefined);
                if (upload === true) {
                    setProgress(100);
                    return;
                }
                const throttleSetProgress = debounce(setProgress, 250);
                const unsubscribe = upload.on("state_changed", (s) => {
                    const progress = (s.bytesTransferred * 100) / s.totalBytes;
                    throttleSetProgress(progress);
                });
                return () => {
                    unsubscribe();
                };
            }, [upload]);
            return (_jsxs(_Fragment, { children: [_jsx(FileInput, { states: {
                            fileProvided: {
                                title: c.title,
                                description: c.fileUsageDescription,
                            },
                            waitingFile: {
                                title: c.title,
                                description: c.fileUsageDescription,
                            },
                        }, footer: c.footer, onFile: (file) => {
                            onAnswer(type, c.id, ans(file));
                        }, file: upload, progress: upload ? progress || 0 : undefined, accept: c.extensions.map((x) => `.${x}`).join(",") }), error ? (_jsx(OneText, { type: "caption", color: "error", children: error })) : null, _jsx(Spacing, { size: "large" })] }));
        case "radio":
            const selected = val();
            return (_jsxs(_Fragment, { children: [_jsx(OneText, { type: titleVariant, children: c.title }), error && (_jsx(OneText, { type: "caption", color: "error", children: error })), _jsx("br", {}), c.options.map((el) => (_jsxs(_Fragment, { children: [_jsx(OneText, { type: labelVariant, children: _jsx(Radio, { checked: selected === el.value, label: el.label, onToggle: () => onAnswer(type, c.id, el.value), groupId: c.id, value: el.value, "data-testid": props["data-testid"] }) }), _jsx("br", {})] })))] }));
        case "check":
            const checkError = typeof error === "string" ? c.options.map(() => error) : error;
            const checkmarks = val() || [];
            return (_jsxs(_Fragment, { children: [_jsx(OneText, { type: titleVariant, children: c.title }), _jsx("br", {}), c.options.map((el, i) => (_jsxs(_Fragment, { children: [_jsx(OneText, { type: labelVariant, children: _jsx(CheckBox, { checked: checkmarks[i], label: _jsx(_Fragment, { children: _jsx("div", { children: el.label }) }), onToggle: (checked) => {
                                        const clone = [...checkmarks];
                                        clone[i] = checked;
                                        onAnswer(type, c.id, clone);
                                    }, groupId: c.id, value: el.value }) }), _jsx("br", {})] }))), _jsx(AdaptiveContainer, { direction: "v", children: Array.isArray(checkError) ? (checkError.some((a) => !!a) ? (_jsx(Text, { title: typeof error === "string" ? error : "", type: variants.error ?? "error", children: error }, "error")) : (_jsx(Fragment, {}, "e"))) : !!checkError ? (_jsx(Text, { title: typeof error === "string" ? error : "", type: variants.error ?? "error", children: error }, "error-single")) : (_jsx(Fragment, {}, "e")) })] }));
        case "rawcheck":
            const rawCheckmarks = val() || [];
            return (_jsxs(_Fragment, { children: [error && (_jsxs(_Fragment, { children: [_jsx(OneText, { type: "caption", color: "error", children: error }), _jsx("br", {})] })), c.options.map((el, i) => (_jsxs(_Fragment, { children: [_jsx(OneText, { type: labelVariant, children: _jsx(CheckBox, { checked: rawCheckmarks[i], label: el.label, onToggle: (checked) => {
                                        const clone = [...rawCheckmarks];
                                        clone[i] = checked;
                                        onAnswer(type, c.id, clone);
                                    }, groupId: c.id, value: el.value }) }), _jsx("br", {})] })))] }));
        case "select":
            return (_jsxs(_Fragment, { children: [_jsx(OneText, { type: titleVariant, children: c.title }), _jsx(Select, { "data-testid": props["data-testid"], alignTo: AnchoredTooltipAlignment.LEFT, items: c.options, selected: val(), onClick: (i) => {
                            onAnswer(type, c.id, i.value);
                        }, filter: c.filter, error: error, disabled: props.disabled })] }));
        case "text":
        case "number":
            const filter = type === "number"
                ? (val) => val.replace(/[^0-9]+/g, "")
                : (val) => val;
            return (_jsxs(_Fragment, { children: [_jsx(OneText, { type: titleVariant, children: c.title }), _jsx(Input, { multiline: "multiline" in c ? c.multiline : undefined, placeholder: c.title, value: val(), error: error, onChange: ({ target: { value } }) => {
                            onAnswer(type, c.id, filter(value));
                        }, "data-testid": props["data-testid"], disabled: props.disabled })] }));
        default:
            const registeredExtension = extensions?.[type];
            if (registeredExtension) {
                const { Input } = registeredExtension;
                return (_jsx(Input, { onAnswer: onAnswer, question: c, value: value, error: error, "data-testid": props["data-testid"] }));
            }
            throw new Error(`The form field "${type}" is not implemented yet. Please provide it using OneUIProvider config options for form extensions`);
    }
}
//# sourceMappingURL=FormField.js.map