import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
import * as React from 'react';
import _ from 'lodash';
import AnyOfDynamicField from "./components/Fields/AnyOf/AnyOf.js";
import ArrayDynamicField from "./components/Fields/Array/Array.js";
import BooleanDynamicField from "./components/Fields/Boolean/Boolean.js";
import NumberDynamicField from "./components/Fields/Number/Number.js";
import ObjectDynamicField from "./components/Fields/Object/Object.js";
import OneOfDynamicField from "./components/Fields/OneOf/OneOf.js";
import SelectDynamicField from "./components/Fields/Select/Select.js";
import TextDynamicField from "./components/Fields/Text/Text.js";
import TextAreaDynamicField from "./components/Fields/TextArea/TextArea.js";
import { formGeneratorCn } from "./utils/cn.js";
import { getContent, getFullPath } from "./utils/common.js";
import './FormGenerator.css';
const b = formGeneratorCn('form-generator');
export const FormGenerator = ({ blockConfig, onUpdateByKey, onUpdate, contentConfig, }) => {
    const inputs = blockConfig;
    const onDataUpdate = React.useCallback((key, value) => {
        if (onUpdateByKey) {
            onUpdateByKey(key, value);
        }
        if (onUpdate && contentConfig) {
            const newContentConfig = _.cloneDeep(contentConfig);
            _.set(newContentConfig, key, value);
            onUpdate(newContentConfig);
        }
    }, [onUpdateByKey, onUpdate, contentConfig]);
    const getData = React.useCallback((variable) => {
        if (variable.startsWith('block.')) {
            const purePath = variable.replace('block.', '');
            return _.get(contentConfig, purePath);
        }
        if ((variable.startsWith(`'`) && variable.endsWith(`'`)) ||
            (variable.startsWith(`"`) && variable.endsWith(`"`))) {
            // @ts-ignore TODO: replaceAll types
            return variable.replaceAll(`'`, '').replaceAll(`"`, '');
        }
        return undefined;
    }, [contentConfig]);
    const decide = React.useCallback((showIf) => {
        const parts = showIf.split(' ');
        if (!(parts.length === 3)) {
            // eslint-disable-next-line no-console
            console.log('Something bad happened in showIf, ignored');
            return true;
        }
        const [firstVariable, equals, secondVariable] = parts;
        const data1 = getData(firstVariable);
        const data2 = getData(secondVariable);
        if (equals === '===') {
            return data1 === data2;
        }
        else {
            return data1 !== data2;
        }
    }, [getData]);
    const renderInput = React.useCallback((input) => {
        const fieldPath = input.name;
        const fieldValue = getContent(contentConfig, input.name);
        if (input.showIf) {
            const decision = decide(input.showIf);
            if (!decision) {
                return _jsxs("div", { children: ["Hidden Field: ", input.name] });
            }
        }
        // Text, Select, Boolean and etc
        const onSimpleDynamicFieldUpdate = (value) => {
            onDataUpdate(fieldPath, value);
        };
        // Array and Objects
        const onComplexDynamicFieldUpdate = (key, value) => {
            onDataUpdate(getFullPath(fieldPath, key), value);
        };
        switch (input.type) {
            case 'text': {
                return (_jsx(TextDynamicField, { onRefresh: (value) => onDataUpdate(fieldPath, value), title: input.title, value: fieldValue, onUpdate: onSimpleDynamicFieldUpdate }));
            }
            case 'boolean': {
                return (_jsx(BooleanDynamicField, { onRefresh: (value) => onDataUpdate(fieldPath, value), title: input.title, value: fieldValue, onUpdate: onSimpleDynamicFieldUpdate }));
            }
            case 'textarea': {
                return (_jsx(TextAreaDynamicField, { onRefresh: (value) => onDataUpdate(fieldPath, value), title: input.title, value: fieldValue, onUpdate: onSimpleDynamicFieldUpdate }));
            }
            case 'select': {
                return (_jsx(SelectDynamicField, { onRefresh: (value) => onDataUpdate(fieldPath, value), input: input, value: fieldValue, onUpdate: onSimpleDynamicFieldUpdate }));
            }
            case 'number': {
                return (_jsx(NumberDynamicField, { onRefresh: (value) => onDataUpdate(fieldPath, value), title: input.title, value: fieldValue, onUpdate: onSimpleDynamicFieldUpdate }));
            }
            case 'object': {
                if (!input || !('properties' in input)) {
                    return null;
                }
                return (_jsx(ObjectDynamicField, { onRefresh: (value) => onDataUpdate(fieldPath, value), blockConfig: input.properties, title: input.title, value: fieldValue, onUpdate: onComplexDynamicFieldUpdate }));
            }
            case 'array': {
                return (_jsx(ArrayDynamicField, { blockConfig: input, title: input.title, values: fieldValue, onUpdate: onComplexDynamicFieldUpdate }));
            }
            case 'oneOf': {
                if (!input || !('options' in input)) {
                    return null;
                }
                return (_jsx(OneOfDynamicField, { inputConfig: input, contentConfig: contentConfig, onUpdate: onComplexDynamicFieldUpdate }));
            }
            case 'anyOf': {
                if (!input || !('options' in input)) {
                    return null;
                }
                return (_jsx(AnyOfDynamicField, { inputConfig: input, contentConfig: contentConfig, onUpdate: onComplexDynamicFieldUpdate }));
            }
            default: {
                return _jsxs("div", { children: ["Ignore ", JSON.stringify(input)] });
            }
        }
    }, [contentConfig, decide, onDataUpdate]);
    const sortedInputs = inputs.sort((x, y) => {
        const nestingFieldTypes = ['object', 'array', 'oneOf', 'anyOf'];
        if (nestingFieldTypes.includes(x.type)) {
            return 1;
        }
        if (nestingFieldTypes.includes(y.type)) {
            return -1;
        }
        return 0;
    });
    return (_jsx("div", { className: b(), children: sortedInputs.map((input, index) => (_jsx(React.Fragment, { children: renderInput(input) }, index))) }));
};
export default FormGenerator;
//# sourceMappingURL=FormGenerator.js.map
