"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OneOfCustom = void 0;
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const React = tslib_1.__importStar(require("react"));
const dynamic_forms_1 = require("@gravity-ui/dynamic-forms");
const ajv_1 = tslib_1.__importDefault(require("ajv"));
const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty.js"));
const utils_1 = require("../../../../utils/index.js");
const useOneOf_1 = require("../../hooks/useOneOf.js");
const b = (0, utils_1.block)('one-of-custom');
const ajv = new ajv_1.default({
    $data: true,
    strict: false,
    strictSchema: false,
    strictTypes: false,
    strictRequired: false,
});
const getOneOfCustomSpecDefaultType = (spec) => spec.viewSpec?.order?.[0] || Object.keys(spec.properties || {})[0];
// dynamic-forms pass {} as default value for required properties of all types
// this function replaces {} with default value accordingly to selected OneOf option spec type
const getControllerDefautValue = (value, valueSpecType) => {
    const isDefaultValue = typeof value === 'object' && (0, isEmpty_1.default)(value);
    const defaultValue = valueSpecType ? (0, useOneOf_1.getSpecTypeDefaultValue)(valueSpecType) : undefined;
    return isDefaultValue ? defaultValue : value;
};
/**
 * Customization of @gravity-ui/dynamic-forms OneOf component
 *
 * Main differences from original component:
 *
 * 1. Custom component can detect initial data type by it's json schema passed it __schema property of spec and
 * shows according input
 *
 * 2. Custom component doesn't create additional nested level of data for each OneOf option and doesn't wraps data value, e.g.
 *
 * custom component: {propertyName: propertyValue}
 * original component: {propertyName: {option1: {value: propertyValue}}}
 *
 * @param {ObjectIndependentInputProps} props - props of original OneOf component
 * @returns {React.FC<ObjectIndependentInputProps>}
 */
const OneOfCustom = (props) => {
    const { spec, input, name } = props;
    const { properties } = spec;
    //getting oneOf option type from initial value
    const valueType = React.useMemo(() => (properties &&
        Object.keys(properties)?.find((key) => {
            const fieldSchema = (properties?.[key]).__schema;
            return fieldSchema && ajv.validate(fieldSchema, (0, dynamic_forms_1.transformArrOut)(input.value));
        })) ||
        getOneOfCustomSpecDefaultType(spec), 
    // eslint-disable-next-line react-hooks/exhaustive-deps
    []);
    const { oneOfValue, specProperties, toggler } = (0, useOneOf_1.useOneOf)({
        props: {
            ...props,
            input: {
                ...input,
                value: valueType ? { [valueType]: input.value } : input.value,
            },
        },
    });
    const parentOnChange = React.useCallback((_childName, childValue, childErrors) => {
        input.onChange(childValue, childErrors);
    }, [input]);
    const parentOnUnmount = React.useCallback((childName) => input.onChange((currentValue) => currentValue, { [childName]: false }), [input]);
    const valueSpecType = specProperties[oneOfValue]?.type || dynamic_forms_1.SpecTypes.Object;
    return ((0, jsx_runtime_1.jsxs)("div", { className: b(), children: [(0, jsx_runtime_1.jsx)("div", { children: toggler }), specProperties[oneOfValue] && ((0, jsx_runtime_1.jsx)(dynamic_forms_1.GroupIndent, { children: (0, jsx_runtime_1.jsx)(dynamic_forms_1.Controller, { value: getControllerDefautValue(input.value, valueSpecType), name: name, spec: specProperties[oneOfValue], parentOnChange: parentOnChange, parentOnUnmount: parentOnUnmount }, `${name}.${oneOfValue}`) }))] }));
};
exports.OneOfCustom = OneOfCustom;
//# sourceMappingURL=OneOfCustom.js.map
