import React, { useState } from 'react';
import { Box, useFocus, Text, useInput } from 'ink';
import { getManager } from './managers/managers.js';
import { DescriptionRenderer } from './DescriptionRenderer.js';
export const FormFieldRenderer = props => {
    const manager = getManager(props.field.type, props.customManagers);
    const [error, setError] = useState();
    const [currentValue, setCurrentValue] = useState(props.value ?? props.field.initialValue);
    const isEditing = !!props.editingField && props.editingField === (props.field.label ?? props.field.name);
    const hide = !isEditing && !!props.editingField;
    const save = (newValue) => {
        if (!error) {
            if (newValue) {
                props.onChange(newValue);
                setCurrentValue(newValue);
            }
            else {
                props.onChange(currentValue);
            }
            props.onSetEditingField(undefined);
        }
    };
    const cancel = () => {
        setCurrentValue(props.value);
        props.onSetEditingField(undefined);
        setError(undefined);
    };
    const { isFocused } = useFocus({});
    useInput((input, key) => {
        if (!isEditing && key.return && !key.ctrl && !key.meta) {
            props.onSetEditingField(props.field.label ?? props.field.name);
        }
        else if (isEditing && key.escape) {
            cancel();
        }
        else if (isEditing && key.return && (!manager?.needCtrlToReturnSave || key.ctrl)) {
            save();
        }
    }, { isActive: isFocused });
    if (hide) {
        return null;
    }
    if (!isEditing) {
        const RenderValue = manager?.renderValue ?? (() => React.createElement(React.Fragment, null, props.value));
        return (React.createElement(Box, { marginX: 2, paddingX: 1, borderStyle: "round", borderColor: isFocused ? 'blue' : undefined },
            React.createElement(Box, { flexGrow: 1 },
                React.createElement(Text, { underline: isFocused, color: isFocused ? 'blue' : undefined }, props.field.label ?? props.field.name),
                props.field.required && React.createElement(Text, { color: "red" }, "*"),
                React.createElement(Text, null, ": "),
                React.createElement(Text, { dimColor: true },
                    React.createElement(RenderValue, { value: props.value, field: props.field }))),
            isFocused && (React.createElement(Box, null,
                React.createElement(Text, null, "Press enter to edit")))));
    }
    else {
        let component;
        const rendererProps = {
            ...props,
            onError: setError,
            onClearError: () => setError(undefined),
            onChange: setCurrentValue,
            value: currentValue,
            onSave: save,
            onCancel: cancel,
            error,
        };
        if (!manager) {
            component = React.createElement(Text, { color: "red" },
                "No formfield manager for form field of type ",
                props.field.type,
                " available.");
        }
        else {
            const Field = manager.renderField;
            component = React.createElement(Field, { ...rendererProps });
        }
        return (React.createElement(Box, { paddingX: 3, paddingY: 1, flexDirection: "column" },
            React.createElement(Box, null,
                React.createElement(Text, null, props.field.label ?? props.field.name),
                props.field.required && React.createElement(Text, { color: "red" }, "*"),
                React.createElement(Text, null, ": ")),
            React.createElement(Box, null, component),
            props.field.description && (React.createElement(Box, null,
                React.createElement(Text, { dimColor: true },
                    React.createElement(DescriptionRenderer, { description: props.field.description })))),
            error && (React.createElement(Box, null,
                React.createElement(Text, { color: "red" },
                    "Error: ",
                    error))),
            React.createElement(Box, { marginTop: 2 },
                React.createElement(Text, { dimColor: true }, error ? (React.createElement(React.Fragment, null, "Press ESC to cancel.")) : (React.createElement(React.Fragment, null,
                    "Press ",
                    manager?.needCtrlToReturnSave ? 'CTRL+Enter' : 'Enter',
                    " to complete field, or ESC to cancel."))))));
    }
};
