"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AdaptableFormComponent = exports.AdaptableFormComponentButtons = void 0;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const rebass_1 = require("rebass");
const FormLayout_1 = tslib_1.__importStar(require("../FormLayout"));
const Input_1 = tslib_1.__importDefault(require("../Input"));
const SimpleButton_1 = tslib_1.__importDefault(require("../SimpleButton"));
const AdaptableInput_1 = tslib_1.__importDefault(require("../../View/Components/AdaptableInput"));
const DropdownButton_1 = tslib_1.__importDefault(require("../DropdownButton"));
const react_1 = require("react");
const AdaptableContext_1 = require("../../View/AdaptableContext");
function AdaptableFormComponentButtons({ formDef, onClick, defaultTone, disabledButtons, api, context, focusFirstButton = true, }) {
    return (React.createElement(React.Fragment, null, formDef.buttons.map((button, index) => {
        var _a;
        const buttonIcon = api.internalApi.getIconForButton(button, context, {
            height: 15,
            width: 15,
        });
        let buttonStyle = api.internalApi.getStyleForButton(button, context
            ? context
            : Object.assign({}, api.internalApi.buildBaseContext()));
        let buttonLabel = api.internalApi.getLabelForButton(button, context
            ? context
            : Object.assign({}, api.internalApi.buildBaseContext()));
        let buttonTooltip = api.internalApi.getTooltipForButton(button, context
            ? context
            : Object.assign({}, api.internalApi.buildBaseContext()));
        return (React.createElement(SimpleButton_1.default, { autoFocus: focusFirstButton && index === 0, disabled: disabledButtons[index], key: index, tooltip: buttonTooltip, icon: buttonIcon, tone: (_a = buttonStyle === null || buttonStyle === void 0 ? void 0 : buttonStyle.tone) !== null && _a !== void 0 ? _a : defaultTone, variant: buttonStyle === null || buttonStyle === void 0 ? void 0 : buttonStyle.variant, "data-text": buttonLabel, className: buttonStyle === null || buttonStyle === void 0 ? void 0 : buttonStyle.className, marginLeft: index ? 2 : 0, onClick: () => {
                onClick(button);
            } }, buttonLabel));
    })));
}
exports.AdaptableFormComponentButtons = AdaptableFormComponentButtons;
function AdaptableFormComponent({ formDef, data, onChange, onButtonClick, displayTitle, api, context, focusFirstButton, }) {
    var _a, _b, _c;
    const getFieldValue = (key) => data[key];
    const setFieldValue = (key, value) => {
        const newData = Object.assign(Object.assign({}, data), { [key]: value });
        onChange(newData);
    };
    const adaptable = (0, AdaptableContext_1.useAdaptable)();
    const disabledButtons = (0, react_1.useMemo)(() => {
        var _a, _b;
        return (_b = (_a = formDef.buttons) === null || _a === void 0 ? void 0 : _a.map((button) => {
            // defensive programming: conventionally context should ALWAYS be present for validating buttons
            const isValid = !!button.disabled && !!context ? !button.disabled(button, context) : true;
            return !isValid;
        })) !== null && _b !== void 0 ? _b : [];
    }, [data]);
    const renderLabel = (field) => {
        return (React.createElement(rebass_1.Box, { className: 'ab-FormLayout_column--label', style: { textAlign: 'end' } }, field.label));
    };
    const renderField = (field) => {
        var _a;
        const value = (_a = getFieldValue(field.name)) !== null && _a !== void 0 ? _a : '';
        const onChange = (event) => {
            if (field.fieldType === 'number') {
                const numberValue = Number(event.target.value);
                if (isNaN(numberValue)) {
                    setFieldValue(field.name, null);
                }
                else {
                    setFieldValue(field.name, numberValue);
                }
            }
            else {
                setFieldValue(field.name, event.target.value);
            }
        };
        switch (field.fieldType) {
            case 'text':
            case 'number':
            case 'date':
                return (React.createElement(AdaptableInput_1.default, { type: field.fieldType, style: { width: '100%' }, name: field.name, value: value, onChange: onChange }));
            case 'select':
                let items = field.options.map((item) => ({
                    value: item.value,
                    label: item.label,
                    onClick: () => setFieldValue(field.name, item.value),
                }));
                return (React.createElement(DropdownButton_1.default, { style: {
                        width: '100%',
                        whiteSpace: 'nowrap',
                        overflow: 'hidden',
                        textOverflow: 'ellipsis',
                        fontSize: 'small',
                    }, items: items, className: "ab-options__select", variant: "outlined", columns: ['label'] }, value));
            case 'checkbox':
                return (React.createElement(Input_1.default, { type: "checkbox", name: field.name, checked: value, onChange: (event) => {
                        setFieldValue(field.name, event.target.checked);
                    } }));
            case 'textOutput':
                return (React.createElement(rebass_1.Box, { paddingLeft: 2, style: { textAlign: 'left' } }, value));
            default:
                return React.createElement("div", null,
                    "Unknown field type: ",
                    field.fieldType);
        }
    };
    // by default we have 2 columns: label & input
    const columns = (_b = (_a = formDef.config) === null || _a === void 0 ? void 0 : _a.columns) !== null && _b !== void 0 ? _b : [1, 2];
    return (React.createElement(React.Fragment, null,
        displayTitle && formDef.title && (React.createElement(rebass_1.Box, { "data-name": "form-title", fontSize: 5, mb: 2, style: { fontWeight: 'bold' } }, formDef.title)),
        formDef.description && (React.createElement(rebass_1.Box, { "data-name": "form-description", mb: 3 }, formDef.description)),
        React.createElement(FormLayout_1.default, { onKeyDown: (event) => {
                const target = event.target;
                const targetName = target.name;
                const field = formDef.fields
                    .map((field) => {
                    if (Array.isArray(field)) {
                        return field.filter((f) => f.name === targetName)[0];
                    }
                    else {
                        return field.name === targetName ? field : null;
                    }
                })
                    .filter(Boolean)[0];
                if (field && field.fieldType === 'number') {
                    // for number fields
                    // hook them up to the CellEditorKeyDown event
                    // so Shortcuts work as expected
                    const value = event.target.value;
                    adaptable._emit('CellEditorKeyDown', {
                        keyDownEvent: event,
                        cellValue: value,
                        columnId: field.name,
                        updateValueCallback: (updatedValue) => {
                            setFieldValue(field.name, updatedValue);
                        },
                    });
                }
            }, "data-name": "form-content", columns: columns, style: { overflow: 'auto' }, paddingRight: 1 }, (_c = formDef.fields) === null || _c === void 0 ? void 0 : _c.map((field, index) => {
            if (Array.isArray(field)) {
                const rowFields = {};
                field.map((fieldItem, index) => {
                    const rowFieldIndex = 2 * index + 1;
                    rowFields[rowFieldIndex] = renderLabel(fieldItem);
                    rowFields[rowFieldIndex + 1] = renderField(fieldItem);
                });
                return React.createElement(FormLayout_1.FormRow, Object.assign({ key: index }, rowFields));
            }
            else {
                return (React.createElement(FormLayout_1.FormRow, { key: field.name },
                    renderLabel(field),
                    renderField(field)));
            }
        })),
        formDef.buttons ? (React.createElement(rebass_1.Flex, { "data-name": "form-buttons", marginTop: 3, flexDirection: "row", alignItems: "center", justifyContent: "center" },
            React.createElement(AdaptableFormComponentButtons, { focusFirstButton: focusFirstButton, onClick: onButtonClick, disabledButtons: disabledButtons, defaultTone: "success", formDef: formDef, api: api, context: context }))) : null));
}
exports.AdaptableFormComponent = AdaptableFormComponent;
