"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const database_1 = __importDefault(require("lib/hooks/database"));
const save_button_1 = __importDefault(require("components/misc/save-button"));
const lodash_1 = require("lodash");
const antd_1 = require("antd");
const schema_1 = require("@cocalc/util/schema");
const checkbox_1 = __importDefault(require("components/misc/checkbox"));
const integer_slider_1 = __importDefault(require("components/misc/integer-slider"));
const select_with_default_1 = __importDefault(require("components/misc/select-with-default"));
const icon_1 = require("@cocalc/frontend/components/icon");
const misc_1 = require("@cocalc/util/misc");
function useEditTable(query, options) {
    const { loading, value } = (0, database_1.default)(query);
    const [original, setOriginal] = (0, react_1.useState)(undefined);
    const [edited, setEdited0] = (0, react_1.useState)(undefined);
    const [counter, setCounter] = (0, react_1.useState)(0);
    const editedRef = (0, react_1.useRef)(edited);
    editedRef.current = edited;
    function setEdited(update, path) {
        if (!path) {
            // usual setEdited
            setEdited0(update);
            // force a full update
            setCounter(counter + 1);
            return;
        }
        // just edit part of object.
        (0, lodash_1.set)(editedRef.current, path, update);
        setEdited0({ ...editedRef.current });
    }
    (0, react_1.useEffect)(() => {
        if (!loading) {
            setOriginal((0, lodash_1.cloneDeep)(value[(0, lodash_1.keys)(value)[0]]));
            setEdited(value[(0, lodash_1.keys)(value)[0]]);
        }
    }, [loading]);
    function Save() {
        if (edited == null || original == null || options?.noSave)
            return null;
        return ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(save_button_1.default, { style: { marginBottom: "10px" }, edited: edited, original: original, setOriginal: setOriginal, table: (0, lodash_1.keys)(query)[0], onSave: options?.onSave }) }));
    }
    function Heading({ path, title, icon, desc, }) {
        return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("h3", { children: [icon && (0, jsx_runtime_1.jsx)(icon_1.Icon, { name: icon, style: { marginRight: "10px" } }), getTitle(path, title)] }), desc && (0, jsx_runtime_1.jsx)("div", { children: desc })] }));
    }
    function EditBoolean({ path, title, desc, label, icon, }) {
        return ((0, jsx_runtime_1.jsxs)(antd_1.Space, { direction: "vertical", style: { marginTop: "15px" }, children: [(0, jsx_runtime_1.jsx)(Heading, { path: path, title: title, icon: icon, desc: desc }), (0, jsx_runtime_1.jsx)(checkbox_1.default, { defaultValue: (0, lodash_1.get)(schema_1.SCHEMA[(0, lodash_1.keys)(query)[0]].user_query?.get?.fields, path), checked: (0, lodash_1.get)(edited, path), onChange: (checked) => {
                        setEdited(checked, path);
                    }, children: getLabel(path, title, label) })] }));
    }
    // It's very important EditNumber isn't recreated once
    // edited and original are both not null, since the text
    // field would then lose focus.  Also, it has to not be
    // a controlled component, since otherwise edited has to
    // be passed in externally, which is very awkward.
    const EditNumber = (0, react_1.useMemo)(() => {
        if (edited == null || original == null)
            return () => null;
        return ({ path, title, desc, units, min, max, icon, }) => ((0, jsx_runtime_1.jsxs)(antd_1.Space, { direction: "vertical", style: { width: "100%" }, children: [(0, jsx_runtime_1.jsx)(Heading, { path: path, title: title, icon: icon, desc: desc }), (0, jsx_runtime_1.jsx)(integer_slider_1.default, { defaultValue: (0, lodash_1.get)(schema_1.SCHEMA[(0, lodash_1.keys)(query)[0]].user_query?.get?.fields, path), initialValue: (0, lodash_1.get)(edited, path), onChange: (value) => {
                        setEdited(value, path);
                    }, min: min, max: max, units: units })] }));
    }, [edited == null, original == null, counter]);
    const EditSelect = (0, react_1.useMemo)(() => {
        if (edited == null || original == null)
            return () => null;
        return ({ path, title, desc, icon, options, style, }) => ((0, jsx_runtime_1.jsxs)(antd_1.Space, { direction: "vertical", children: [(0, jsx_runtime_1.jsx)(Heading, { path: path, title: title, icon: icon, desc: desc }), (0, jsx_runtime_1.jsx)(select_with_default_1.default, { style: style, defaultValue: (0, lodash_1.get)(schema_1.SCHEMA[(0, lodash_1.keys)(query)[0]].user_query?.get?.fields, path), initialValue: (0, lodash_1.get)(edited, path), onChange: (value) => {
                        setEdited(value, path);
                    }, options: options })] }));
    }, [edited == null, original == null, counter]);
    return {
        edited,
        original,
        Save,
        setEdited,
        EditBoolean,
        EditNumber,
        EditSelect,
        Heading,
    };
}
exports.default = useEditTable;
function getTitle(path, title) {
    if (title)
        return title;
    if (!path)
        return "";
    const v = path.split(".");
    return v[v.length - 1].split("_").map(misc_1.capitalize).join(" ");
}
function getLabel(path, title, label) {
    return label ?? (0, misc_1.capitalize)(getTitle(path, title).toLowerCase());
}
//# sourceMappingURL=edit-table.js.map