/**
 * amis-ui v6.12.0-beta.0
 * Copyright 2018-2025 fex
 */

'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var tslib = require('tslib');
var React = require('react');
var amisCore = require('amis-core');
var Button = require('../Button.js');
var icons = require('../icons.js');
var InputBox = require('../InputBox.js');
var InputBoxWithSuggestion = require('../InputBoxWithSuggestion.js');
var Select = require('../Select.js');
var Item = require('./Item.js');
var isEqual = require('lodash/isEqual');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
var isEqual__default = /*#__PURE__*/_interopDefaultLegacy(isEqual);

var __react_jsx__ = require('react');
var _J$X_ = (__react_jsx__["default"] || __react_jsx__).createElement;
(__react_jsx__["default"] || __react_jsx__).Fragment;
function InputJSONSchemaObject(props, ref) {
    var _a, _b;
    var cx = props.classnames, value = props.value, onChange = props.onChange, disabled = props.disabled, __ = props.translate, renderKey = props.renderKey, collapsable = props.collapsable, renderValue = props.renderValue, mobileUI = props.mobileUI, className = props.className, addButtonText = props.addButtonText;
    var buildMembers = React__default["default"].useCallback(function (schema, value) {
        var e_1, _a;
        var _b;
        var members = [];
        var required = Array.isArray(schema.required) ? schema.required : [];
        Object.keys(schema.properties || {}).forEach(function (key) {
            var _a;
            var child = schema.properties[key];
            members.push({
                key: amisCore.guid(),
                name: key,
                nameMutable: !required.includes(key),
                required: required.includes(key),
                schema: child,
                value: (_a = value === null || value === void 0 ? void 0 : value[key]) !== null && _a !== void 0 ? _a : child.default
            });
        });
        var keys = Object.keys(value || {});
        var _loop_1 = function (key) {
            var exists = members.find(function (m) { return m.name === key; });
            if (!exists && schema.additionalProperties !== false) {
                members.push({
                    key: amisCore.guid(),
                    name: key,
                    nameMutable: true,
                    schema: {
                        type: 'string',
                        default: ''
                    },
                    value: (_b = value[key]) !== null && _b !== void 0 ? _b : ''
                });
            }
        };
        try {
            for (var keys_1 = tslib.__values(keys), keys_1_1 = keys_1.next(); !keys_1_1.done; keys_1_1 = keys_1.next()) {
                var key = keys_1_1.value;
                _loop_1(key);
            }
        }
        catch (e_1_1) { e_1 = { error: e_1_1 }; }
        finally {
            try {
                if (keys_1_1 && !keys_1_1.done && (_a = keys_1.return)) _a.call(keys_1);
            }
            finally { if (e_1) throw e_1.error; }
        }
        if (!members.length && schema.additionalProperties !== false) {
            members.push({
                key: amisCore.guid(),
                name: '',
                nameMutable: true,
                schema: {
                    type: 'string',
                    default: ''
                },
                value: ''
            });
        }
        return members;
    }, []);
    var _c = tslib.__read(React__default["default"].useState([]), 2), members = _c[0], _setMembers = _c[1];
    var membersRef = React__default["default"].useRef();
    membersRef.current = members;
    var setMembers = function (members) {
        _setMembers(members);
        membersRef.current = members;
    };
    var _d = tslib.__read(React__default["default"].useState(collapsable ? true : false), 2), collapsed = _d[0], setCollapsed = _d[1];
    var toggleCollapsed = function () {
        setCollapsed(!collapsed);
    };
    var emitChange = function () {
        var members = membersRef.current;
        var value = {};
        members.forEach(function (member) {
            if (!member.invalid &&
                (typeof member.value !== 'undefined' ||
                    typeof value[member.name] !== 'undefined')) {
                value[member.name] = member.value;
            }
        });
        if (!isEqual__default["default"](value, props.value || {})) {
            onChange === null || onChange === void 0 ? void 0 : onChange(value);
        }
    };
    var onMemberChange = function (member, memberValue) {
        var arr = members.concat();
        var idx = arr.indexOf(member);
        if (!~idx) {
            throw new Error('member object not found');
        }
        arr.splice(idx, 1, tslib.__assign(tslib.__assign({}, arr[idx]), { value: memberValue }));
        setMembers(arr);
        emitChange();
    };
    var onMemberKeyChange = function (member, memberKey) {
        var _a, _b;
        var idx = members.indexOf(member);
        if (!~idx) {
            throw new Error('member object not found');
        }
        var originSchema = members[idx].schema;
        var schema = ((_b = (_a = props.schema) === null || _a === void 0 ? void 0 : _a.properties) === null || _b === void 0 ? void 0 : _b[memberKey]) || {
            type: 'string',
            default: ''
        };
        var arr = members.concat();
        var item = tslib.__assign(tslib.__assign({}, member), { schema: schema, name: memberKey, invalid: !memberKey || members.some(function (a, b) { return a.name === memberKey && b !== idx; })
                ? 'key'
                : undefined });
        if (item.value === originSchema.default &&
            originSchema !== schema &&
            originSchema.default !== schema.default) {
            item.value = schema.default;
        }
        arr.splice(idx, 1, item);
        setMembers(arr);
        emitChange();
    };
    var onMemberDelete = function (member) {
        var idx = members.indexOf(member);
        if (!~idx) {
            throw new Error('member object not found');
        }
        var arr = members.concat();
        arr.splice(idx, 1);
        setMembers(arr);
        emitChange();
    };
    React__default["default"].useEffect(function () {
        var members = buildMembers(props.schema, props.value);
        setMembers(members);
        emitChange();
    }, [JSON.stringify(props.schema)]);
    React__default["default"].useEffect(function () {
        var e_2, _a;
        var _b;
        var value = props.value;
        var arr = membersRef.current.concat();
        var keys = Object.keys(value || {});
        var _loop_2 = function (key) {
            var idx = arr.findIndex(function (m) { return m.name === key; });
            var exists = arr[idx];
            if (!exists && props.schema.additionalProperties !== false) {
                arr.push({
                    key: amisCore.guid(),
                    name: key,
                    nameMutable: true,
                    schema: {
                        type: 'string',
                        default: ''
                    },
                    value: (_b = value === null || value === void 0 ? void 0 : value[key]) !== null && _b !== void 0 ? _b : ''
                });
            }
            else {
                arr.splice(idx, 1, tslib.__assign(tslib.__assign({}, exists), { value: value === null || value === void 0 ? void 0 : value[key] }));
            }
        };
        try {
            for (var keys_2 = tslib.__values(keys), keys_2_1 = keys_2.next(); !keys_2_1.done; keys_2_1 = keys_2.next()) {
                var key = keys_2_1.value;
                _loop_2(key);
            }
        }
        catch (e_2_1) { e_2 = { error: e_2_1 }; }
        finally {
            try {
                if (keys_2_1 && !keys_2_1.done && (_a = keys_2.return)) _a.call(keys_2);
            }
            finally { if (e_2) throw e_2.error; }
        }
        setMembers(arr);
    }, [JSON.stringify(props.value)]);
    var handleAdd = React__default["default"].useCallback(function () {
        var arr = members.concat();
        arr.push({
            key: amisCore.guid(),
            name: '',
            invalid: 'key',
            nameMutable: true,
            schema: {
                type: 'string',
                default: ''
            },
            value: ''
        });
        setMembers(arr);
        emitChange();
    }, [members]);
    var options = [];
    var properties = ((_a = props.schema) === null || _a === void 0 ? void 0 : _a.properties) || {};
    Object.keys(properties).forEach(function (key) {
        var _a;
        options.push({
            label: ((_a = properties[key]) === null || _a === void 0 ? void 0 : _a.title) || key,
            value: key
        });
    });
    // todo additionalProperties 还有其他格式
    var allowAdd = !(props.schema.additionalProperties === false &&
        options.every(function (o) { return members.find(function (m) { return m.name === o.value; }); }));
    var allowInput = props.schema.additionalProperties !== false;
    React__default["default"].useImperativeHandle(ref, function () {
        return {
            validate: function () {
                var _a;
                if ((_a = membersRef.current) === null || _a === void 0 ? void 0 : _a.some(function (m) { return m.invalid === 'key'; })) {
                    return __('JSONSchema.key_invalid');
                }
            }
        };
    });
    return (_J$X_(React__default["default"].Fragment, null,
        collapsable ? (_J$X_("a", { className: cx('JSONSchemaObject-caret', {
                'is-collapsed': collapsed
            }), onClick: toggleCollapsed },
            _J$X_(icons.Icon, { icon: "right-arrow-bold", className: "icon" }))) : null,
        _J$X_("div", { className: cx('JSONSchemaObject', className, {
                'is-mobile': mobileUI,
                'is-expanded': collapsable && !collapsed
            }) },
            collapsed ? (renderValue ? (_J$X_(Item["default"], tslib.__assign({}, props, { value: value, onChange: onChange, schema: {
                    type: 'string'
                }, placeholder: (_b = props.schema) === null || _b === void 0 ? void 0 : _b.description }))) : null) : (members.map(function (member) {
                var _a, _b;
                var filtedOptions = options.filter(function (o) { return !members.find(function (m) { return m !== member && m.name === o.value; }); });
                return (_J$X_("div", { key: member.key, className: cx('JSONSchemaMember') },
                    _J$X_("div", { className: cx('JSONSchemaMember-key', {
                            'is-mobile': mobileUI
                        }) }, member.nameMutable ? (_J$X_(React__default["default"].Fragment, null, renderKey ? (renderKey(member.name, onMemberKeyChange.bind(null, member), member.schema, props)) : filtedOptions.length ? (allowInput ? (_J$X_(InputBoxWithSuggestion["default"], { value: member.name, hasError: member.invalid === 'key', onChange: onMemberKeyChange.bind(null, member), clearable: false, placeholder: __('JSONSchema.key'), options: filtedOptions, mobileUI: mobileUI })) : (_J$X_(Select["default"], { simpleValue: true, block: true, value: member.name, hasError: member.invalid === 'key', onChange: onMemberKeyChange.bind(null, member), clearable: false, placeholder: __('JSONSchema.key'), options: filtedOptions, mobileUI: mobileUI }))) : (_J$X_(InputBox["default"], { value: member.name, hasError: member.invalid === 'key', onChange: onMemberKeyChange.bind(null, member), clearable: false, placeholder: __('JSONSchema.key'), mobileUI: mobileUI })))) : (_J$X_("span", null,
                        member.required ? (_J$X_("span", { className: cx("Form-star") }, "*")) : null,
                        ((_a = member.schema) === null || _a === void 0 ? void 0 : _a.title) || member.name))),
                    _J$X_("div", { className: cx('JSONSchemaMember-value') },
                        _J$X_(Item["default"], tslib.__assign({}, props, { className: "", addButtonText: undefined, required: member.required, value: value === null || value === void 0 ? void 0 : value[member.name], onChange: onMemberChange.bind(null, member), schema: member.schema || {
                                type: 'string'
                            }, placeholder: (_b = member.schema) === null || _b === void 0 ? void 0 : _b.description, collapsable: true }))),
                    !member.required ? (_J$X_(Button["default"], { className: cx('SchemaEditor-btn'), onClick: onMemberDelete.bind(null, member), iconOnly: true, disabled: disabled || !!(value === null || value === void 0 ? void 0 : value.$ref) },
                        _J$X_(icons.Icon, { icon: "remove", className: "icon" }))) : null));
            })),
            allowAdd && !collapsed ? (_J$X_(Button["default"], { level: "link", onClick: handleAdd, size: "xs", disabled: disabled }, addButtonText !== null && addButtonText !== void 0 ? addButtonText : __('JSONSchema.add_prop'))) : null)));
}
var InputJSONSchemaObject$1 = React__default["default"].forwardRef(InputJSONSchemaObject);

exports.InputJSONSchemaObject = InputJSONSchemaObject;
exports["default"] = InputJSONSchemaObject$1;
