import * as React from 'react';
import FormLayout, { FormRow } from '../FormLayout';
import Input from '../Input';
import SimpleButton from '../SimpleButton';
import AdaptableInput from '../../View/Components/AdaptableInput';
import { useMemo } from 'react';
import { useAdaptable } from '../../View/AdaptableContext';
import { Select } from '../Select';
import { Box, Flex } from '../Flex';
import { twMerge } from '../../twMerge';
export function AdaptableFormComponentButtons({ formDef, onClick, defaultTone, disabledButtons, api, context, focusFirstButton = true, }) {
    return (React.createElement(React.Fragment, null, formDef.buttons.map((button, index) => {
        const buttonIcon = api.internalApi.getIconForButton(button, context, {
            height: 15,
            width: 15,
        });
        let buttonStyle = api.internalApi.getStyleForButton(button, context
            ? context
            : {
                ...api.internalApi.buildBaseContext(),
            });
        let buttonLabel = api.internalApi.getLabelForButton(button, context
            ? context
            : {
                ...api.internalApi.buildBaseContext(),
            });
        let buttonTooltip = api.internalApi.getTooltipForButton(button, context
            ? context
            : {
                ...api.internalApi.buildBaseContext(),
            });
        return (React.createElement(SimpleButton, { autoFocus: focusFirstButton && index === 0, disabled: disabledButtons[index], key: index, tooltip: buttonTooltip, icon: buttonIcon, tone: buttonStyle?.tone ?? defaultTone, variant: buttonStyle?.variant, "data-text": buttonLabel, className: twMerge(index ? 'twa:ml-2' : '', buttonStyle?.className), onClick: () => {
                onClick(button);
            } }, buttonLabel));
    })));
}
export function AdaptableFormComponent({ formDef, data, onChange, onButtonClick, displayTitle, api, context, focusFirstButton, }) {
    const getFieldValue = (key) => data[key];
    const setFieldValue = (key, value) => {
        const newData = { ...data, [key]: value };
        onChange(newData);
    };
    const adaptable = useAdaptable();
    const disabledButtons = useMemo(() => formDef.buttons?.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;
    }) ?? [], [data]);
    const renderLabel = (field) => {
        return (React.createElement(Box, { className: 'ab-FormLayout_column--label', style: { textAlign: 'end' } }, field.label));
    };
    const renderField = (field) => {
        const value = getFieldValue(field.name) ?? '';
        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, { type: field.fieldType, className: "twa:w-full", 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(Select, { style: { width: '100%' }, className: `ab-options__select`, options: items, onChange: (newValue) => setFieldValue(field.name, newValue), value: value }));
            case 'checkbox':
                return (React.createElement(Input, { type: "checkbox", name: field.name, checked: value, onChange: (event) => {
                        setFieldValue(field.name, event.target.checked);
                    } }));
            case 'textOutput':
                return React.createElement(Box, { className: "twa:pl-2 twa:text-left" }, value);
            default:
                return React.createElement("div", null,
                    "Unknown field type: ",
                    field.fieldType);
        }
    };
    // by default we have 2 columns: label & input
    const columns = formDef.config?.columns ?? [1, 2];
    return (React.createElement(React.Fragment, null,
        displayTitle && formDef.title && (React.createElement(Box, { "data-name": "form-title", className: "twa:text-5 twa:mb-2 twa:font-bold" }, formDef.title)),
        formDef.description && (React.createElement(Box, { "data-name": "form-description", className: "twa:mb-3" }, formDef.description)),
        React.createElement(FormLayout, { 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, className: "twa:pr-1 twa:overflow-auto" }, formDef.fields?.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(FormRow, { key: index, ...rowFields });
            }
            else {
                return (React.createElement(FormRow, { key: field.name },
                    renderLabel(field),
                    renderField(field)));
            }
        })),
        formDef.buttons ? (React.createElement(Flex, { "data-name": "form-buttons", className: "twa:mt-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));
}
