"use strict";
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __read = (this && this.__read) || function (o, n) {
    var m = typeof Symbol === "function" && o[Symbol.iterator];
    if (!m) return o;
    var i = m.call(o), r, ar = [], e;
    try {
        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
    }
    catch (error) { e = { error: error }; }
    finally {
        try {
            if (r && !r.done && (m = i["return"])) m.call(i);
        }
        finally { if (e) throw e.error; }
    }
    return ar;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var jsx_runtime_1 = require("react/jsx-runtime");
var react_1 = require("react");
var database_1 = __importDefault(require("lib/hooks/database"));
var save_button_1 = __importDefault(require("components/misc/save-button"));
var lodash_1 = require("lodash");
var antd_1 = require("antd");
var schema_1 = require("@cocalc/util/schema");
var checkbox_1 = __importDefault(require("components/misc/checkbox"));
var integer_slider_1 = __importDefault(require("components/misc/integer-slider"));
var select_with_default_1 = __importDefault(require("components/misc/select-with-default"));
var icon_1 = require("@cocalc/frontend/components/icon");
var misc_1 = require("@cocalc/util/misc");
function useEditTable(query, options) {
    var _a = (0, database_1.default)(query), loading = _a.loading, value = _a.value;
    var _b = __read((0, react_1.useState)(undefined), 2), original = _b[0], setOriginal = _b[1];
    var _c = __read((0, react_1.useState)(undefined), 2), edited = _c[0], setEdited0 = _c[1];
    var _d = __read((0, react_1.useState)(0), 2), counter = _d[0], setCounter = _d[1];
    var 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(__assign({}, editedRef.current));
    }
    (0, react_1.useEffect)(function () {
        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 === null || options === void 0 ? void 0 : 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 === null || options === void 0 ? void 0 : options.onSave }) }));
    }
    function Heading(_a) {
        var path = _a.path, title = _a.title, icon = _a.icon, desc = _a.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(_a) {
        var _b, _c;
        var path = _a.path, title = _a.title, desc = _a.desc, label = _a.label, icon = _a.icon;
        return ((0, jsx_runtime_1.jsxs)(antd_1.Space, __assign({ 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, __assign({ defaultValue: (0, lodash_1.get)((_c = (_b = schema_1.SCHEMA[(0, lodash_1.keys)(query)[0]].user_query) === null || _b === void 0 ? void 0 : _b.get) === null || _c === void 0 ? void 0 : _c.fields, path), checked: (0, lodash_1.get)(edited, path), onChange: function (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.
    var EditNumber = (0, react_1.useMemo)(function () {
        if (edited == null || original == null)
            return function () { return null; };
        return function (_a) {
            var _b, _c;
            var path = _a.path, title = _a.title, desc = _a.desc, units = _a.units, min = _a.min, max = _a.max, icon = _a.icon;
            return ((0, jsx_runtime_1.jsxs)(antd_1.Space, __assign({ 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)((_c = (_b = schema_1.SCHEMA[(0, lodash_1.keys)(query)[0]].user_query) === null || _b === void 0 ? void 0 : _b.get) === null || _c === void 0 ? void 0 : _c.fields, path), initialValue: (0, lodash_1.get)(edited, path), onChange: function (value) {
                            setEdited(value, path);
                        }, min: min, max: max, units: units })] })));
        };
    }, [edited == null, original == null, counter]);
    var EditSelect = (0, react_1.useMemo)(function () {
        if (edited == null || original == null)
            return function () { return null; };
        return function (_a) {
            var _b, _c;
            var path = _a.path, title = _a.title, desc = _a.desc, icon = _a.icon, options = _a.options, style = _a.style;
            return ((0, jsx_runtime_1.jsxs)(antd_1.Space, __assign({ 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)((_c = (_b = schema_1.SCHEMA[(0, lodash_1.keys)(query)[0]].user_query) === null || _b === void 0 ? void 0 : _b.get) === null || _c === void 0 ? void 0 : _c.fields, path), initialValue: (0, lodash_1.get)(edited, path), onChange: function (value) {
                            setEdited(value, path);
                        }, options: options })] })));
        };
    }, [edited == null, original == null, counter]);
    return {
        edited: edited,
        original: original,
        Save: Save,
        setEdited: setEdited,
        EditBoolean: EditBoolean,
        EditNumber: EditNumber,
        EditSelect: EditSelect,
        Heading: Heading,
    };
}
exports.default = useEditTable;
function getTitle(path, title) {
    if (title)
        return title;
    if (!path)
        return "";
    var v = path.split(".");
    return v[v.length - 1].split("_").map(misc_1.capitalize).join(" ");
}
function getLabel(path, title, label) {
    return label !== null && label !== void 0 ? label : (0, misc_1.capitalize)(getTitle(path, title).toLowerCase());
}
//# sourceMappingURL=edit-table.js.map