"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = SelectTreeField;
const React = __importStar(require("react"));
const utils_1 = require("../../utils");
const react_1 = require("react");
/**
 * Constructs selects from given tree.
 * uiSchema = {"ui:options": {
*   tree: {<enum key tree>}, (node object: {children: {key: {<node>}, key2:{<node>}}, order: ["key", "key2"]} (order is optional)
*   labels: [<string>]
 * }
 */
function SelectTreeField(props) {
    const childProps = getChildProps(props);
    const { onChange: parentOnChange } = props;
    const { formData: childFormData } = childProps;
    const onChange = (0, react_1.useCallback)((formData) => {
        let selectNames = Object.keys(formData).sort((a, b) => { return +b - +a; });
        for (let i in selectNames) {
            if (formData[i] !== childFormData[i]) {
                let value;
                if ((0, utils_1.isEmptyString)(formData[i])) {
                    value = (+i > 0) ? formData[+i - 1] : undefined;
                }
                else {
                    value = formData[i];
                }
                parentOnChange(value);
                break;
            }
        }
    }, [childFormData, parentOnChange]);
    const SchemaField = props.registry.fields.SchemaField;
    return React.createElement(SchemaField, Object.assign({}, props, childProps, { onChange: onChange }));
}
const getChildProps = (props) => {
    let schema = { "type": "object", title: props.schema.title };
    let formData = {};
    let idSchema = { $id: props.idSchema.$id };
    let dictionarifiedEnums = {};
    props.schema.oneOf.forEach((e) => {
        dictionarifiedEnums[e.const] = e.title;
    });
    const tree = (0, utils_1.getUiOptions)(props.uiSchema).tree;
    let levels = [];
    let parentsMap = {};
    let childrenMap = {};
    let orderMap = {};
    function getLevels(tree, depth, root) {
        childrenMap[root] = {};
        if (!tree.children) {
            return;
        }
        Object.keys(tree.children).forEach(key => {
            if (!levels[depth])
                levels[depth] = {};
            levels[depth][key] = true;
            parentsMap[key] = root;
            childrenMap[root][key] = true;
            getLevels(tree.children[key], depth + 1, key);
        });
        orderMap[root] = tree.order;
    }
    getLevels(tree, 0);
    let properties = {};
    function addSelect(depth, key, childrenKeys) {
        let select = { type: "string", oneOf: [{ const: "", title: "" }] };
        let order = orderMap[key];
        if (order) {
            childrenKeys.sort((a, b) => { return order.indexOf(a) - order.indexOf(b); });
        }
        childrenKeys.forEach(key => {
            select.oneOf.push({ const: key, title: dictionarifiedEnums[key] });
        });
        select.title = "";
        properties[depth] = select;
        idSchema[depth] = { $id: idSchema.$id + "_" + depth };
    }
    let searchTerm = props.formData;
    let depth = 0;
    if (!(0, utils_1.isEmptyString)(searchTerm)) {
        for (const level of levels) {
            if (level[searchTerm])
                break;
            depth++;
        }
    }
    let n = searchTerm;
    let d = depth;
    while (d >= 0) {
        formData[d] = n;
        if ((0, utils_1.isEmptyString)(n)) {
            n = undefined; // object keys can't be "", so root key is in childrenMap 'undefined'.
        }
        addSelect(d, n, Object.keys(childrenMap[parentsMap[n]]));
        d--;
        n = parentsMap[n];
    }
    if (!(0, utils_1.isEmptyString)(searchTerm) && childrenMap[searchTerm] && Object.keys(childrenMap[searchTerm]).length) {
        addSelect(depth + 1, searchTerm, Object.keys(childrenMap[searchTerm]));
        formData[depth + 1] = undefined;
    }
    schema.properties = properties;
    return { schema, formData, uiSchema: (0, utils_1.getInnerUiSchema)(props.uiSchema), idSchema };
};
