"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 __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
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;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const React = __importStar(require("react"));
const PropTypes = __importStar(require("prop-types"));
const utils_1 = require("../../utils");
const utils_2 = require("@rjsf/utils");
const components_1 = require("../components");
const ArrayFieldTemplate_1 = require("../templates/ArrayFieldTemplate");
const ReactContext_1 = __importDefault(require("../../ReactContext"));
const specialRules = {
    legEditors: {
        filterProperties: ({ properties, formData, uiSchemaContext }) => {
            if (!uiSchemaContext)
                return properties;
            const { creator } = uiSchemaContext;
            return (!formData ||
                formData.some(item => item && item.leg && item.leg.match(/MA\.\d+/) && item.leg !== creator)) ? properties : properties.filter(field => field !== "editors");
        }
    }
};
const specialRulesPropTypes = PropTypes.oneOf(["legEditors"]);
class TableField extends React.Component {
    render() {
        const { schema, uiSchema = {}, formData, registry: { fields: { ArrayField } }, formContext } = this.props;
        const { uiSchemaContext } = formContext;
        const schemaProps = schema.additionalItems ? schema.additionalItems.properties : schema.items.properties;
        const options = (0, utils_1.getUiOptions)(uiSchema);
        let schemaPropsArray = Object.keys(schemaProps);
        const optionsSpecialRules = options.specialRules;
        if (optionsSpecialRules) {
            (Array.isArray(optionsSpecialRules) ? optionsSpecialRules : [optionsSpecialRules]).forEach(specialRule => {
                schemaPropsArray = specialRules[specialRule].filterProperties({
                    properties: schemaPropsArray, uiSchema, uiSchemaContext, formData
                });
            });
        }
        const schemaLength = schemaPropsArray.filter(col => !(0, utils_1.isHidden)(uiSchema.items, col)).length;
        const defaultCol = parseInt(12 / schemaLength);
        const defaultWrapperCol = parseInt(12 / (1 + (Object.keys(schemaProps).filter(col => !(0, utils_1.isHidden)(uiSchema.items, col)).length - schemaLength)));
        const cols = { xs: undefined, sm: undefined, md: undefined, lg: undefined };
        const wrapperCols = Object.assign({}, cols);
        Object.keys(cols).forEach(col => {
            cols[col] = options[col] ? Math.min(options[col], defaultCol) : defaultCol;
            wrapperCols[col] = options[col] ? Math.min(options[col], defaultWrapperCol) : defaultWrapperCol;
        });
        const itemsSchema = schemaPropsArray.reduce((constructedSchema, prop) => {
            constructedSchema.properties[prop] = schema.items.properties[prop];
            return constructedSchema;
        }, Object.assign(Object.assign({}, schema.items), { properties: {} }));
        const itemsUiSchema = {
            "ui:field": "GridLayoutField",
            "ui:options": Object.assign(Object.assign({}, cols), { label: false }),
        };
        let _uiSchema = uiSchema;
        if (uiSchema.items) {
            if (uiSchema.items.uiSchema) {
                _uiSchema = Object.assign(Object.assign({}, _uiSchema), { items: (0, utils_1.updateTailUiSchema)(uiSchema.items, { $merge: { uiSchema: itemsUiSchema } }) });
            }
            else if (uiSchema.items["ui:field"] || uiSchema.items["ui:functions"]) {
                _uiSchema = Object.assign(Object.assign({}, _uiSchema), { items: Object.assign(Object.assign({}, _uiSchema.items), { uiSchema: itemsUiSchema }) });
            }
            else {
                _uiSchema = Object.assign(Object.assign({}, _uiSchema), { items: Object.assign(Object.assign(Object.assign({}, (uiSchema.items || {})), itemsUiSchema), { "ui:options": Object.assign(Object.assign({}, (0, utils_1.getUiOptions)(uiSchema.items)), (0, utils_1.getUiOptions)(itemsUiSchema)) }) });
            }
        }
        _uiSchema["ui:ArrayFieldTemplate"] = TableArrayFieldTemplate;
        const _formContext = Object.assign(Object.assign({}, formContext), { cols,
            wrapperCols,
            schemaPropsArray });
        return (React.createElement(ArrayField, Object.assign({}, this.props, { schema: Object.assign(Object.assign({}, schema), { items: itemsSchema }), uiSchema: _uiSchema, registry: Object.assign(Object.assign({}, this.props.registry), { formContext: _formContext }), formContext: _formContext })));
    }
}
TableField.contextType = ReactContext_1.default;
TableField.propTypes = {
    uiSchema: PropTypes.shape({
        "ui:options": PropTypes.shape({
            specialRules: PropTypes.oneOfType([
                specialRulesPropTypes,
                PropTypes.arrayOf(specialRulesPropTypes)
            ])
        })
    }),
    schema: PropTypes.shape({
        type: PropTypes.oneOf(["array"]),
        items: PropTypes.oneOfType([PropTypes.object, PropTypes.array])
    }).isRequired
};
exports.default = TableField;
let TableArrayFieldTemplate = class TableArrayFieldTemplate extends React.Component {
    render() {
        const { props } = this;
        const { schema, uiSchema, formContext: { cols, wrapperCols, schemaPropsArray, uiSchemaContext }, idSchema, readonly, disabled } = props;
        const schemaProps = schema.additionalItems ? schema.additionalItems.properties : schema.items.properties;
        const { Label } = this.props.formContext;
        const { Row, Col } = this.context.theme;
        const labels = (0, utils_2.orderProperties)(schemaPropsArray.filter(col => !(0, utils_1.isHidden)(uiSchema.items, col)), (uiSchema.items || {})["ui:order"]).map(propName => {
            const propUiSchema = uiSchema && uiSchema.items && uiSchema.items[propName] || {};
            return (React.createElement(Col, Object.assign({}, cols, { key: propName + "-label" }),
                React.createElement(Label, { label: "title" in schemaProps[propName] ? schemaProps[propName].title : propName, disabled: false, id: idSchema[propName].$id, required: (schema.items.required && schema.items.required.indexOf(propName) > -1)
                        || propUiSchema["ui:required"], uiSchema: propUiSchema })));
        });
        const options = (0, utils_1.getUiOptions)(props.uiSchema);
        const { confirmDelete = uiSchemaContext.confirmDelete, deleteCorner, removable = true, nonRemovables = [], buttons, "ui:deleteHelp": deleteHelp } = options;
        if (!this.deleteButtonRefs)
            this.deleteButtonRefs = [];
        const getRefFor = i => elem => { this.deleteButtonRefs[i] = elem; };
        return (React.createElement("div", { className: "table-field" },
            React.createElement(Row, null,
                React.createElement("div", { className: "laji-form-field-template-item" },
                    React.createElement("div", { className: "laji-form-field-template-schema" }, labels),
                    React.createElement("div", { className: "laji-form-field-template-buttons" }))),
            props.items.map((item, i) => {
                const deleteButton = (React.createElement(components_1.DeleteButton, { ref: getRefFor(i), id: `${props.idSchema.$id}_${i}`, disabled: readonly || disabled, onClick: item.onDropIndexClick(item.index), confirm: confirmDelete, corner: deleteCorner, tooltip: deleteHelp, translations: props.formContext.translations }));
                return (React.createElement(Row, { key: (0, utils_1.getUUID)(props.formData[item.index]) || item.key },
                    React.createElement(Col, Object.assign({}, wrapperCols),
                        React.createElement("div", { className: "laji-form-field-template-item keep-vertical" },
                            React.createElement("div", { className: "laji-form-field-template-schema" }, item.children),
                            item.hasRemove && !nonRemovables.includes(item.index) && removable && deleteButton))));
            }),
            (0, ArrayFieldTemplate_1.getButtonElems)(buttons, props)));
    }
};
TableArrayFieldTemplate.contextType = ReactContext_1.default;
TableArrayFieldTemplate = __decorate([
    ArrayFieldTemplate_1.handlesArrayKeys
], TableArrayFieldTemplate);
