import * as React from 'react';
import { Box, Flex } from 'rebass';
import { CheckBox } from '../../../components/CheckBox';
import DropdownButton from '../../../components/DropdownButton';
import HelpBlock from '../../../components/HelpBlock';
import Input from '../../../components/Input';
import StringExtensions from '../../../Utilities/Extensions/StringExtensions';
import { MetamodelService } from '../../../Utilities/Services/MetamodelService';
import { AdaptablePopover } from '../../AdaptablePopover';
const LABEL_WIDTH = 250;
const SUPPORTED_PRIMITEVE_TYPES = ['s', 'n', 'b'];
const OptionInput = (props) => {
    const { name, defaultValue, value, description, uiLabel } = props.option;
    const label = uiLabel ?? StringExtensions.Humanize(name);
    let input = React.createElement(React.Fragment, null);
    const info = (React.createElement(Box, { ml: 2 },
        React.createElement(AdaptablePopover, { headerText: null, bodyText: [description] })));
    const handleInputChange = (event) => props.onChange({ ...props.option, value: event.currentTarget.value });
    const handleCheckboxChange = (checked) => props.onChange({ ...props.option, value: checked });
    // option is mutated to acomodate complex types overrides
    const option = { ...props.option };
    const isOptionNonHomogenusUnion = (option) => {
        const isUnion = option.kind.includes('|');
        return isUnion && option.kind.split('|').some((unionEl) => !/['"]/.test(unionEl));
    };
    if (isOptionNonHomogenusUnion(option)) {
        // pick the first type
        const newKind = option.kind
            .split('|')
            .find((unionEl) => SUPPORTED_PRIMITEVE_TYPES.includes(unionEl.trim()))
            .trim();
        if (newKind)
            option.kind = newKind;
    }
    const inputProps = {
        value: value ?? defaultValue,
        minWidth: 200,
        fontSize: 3,
        mr: 2,
    };
    if (option.kind.includes('|')) {
        const options = option.kind
            .split('|')
            .map((str) => str.trim().replace(/['"]/g, ''))
            .map((str) => ({
            label: StringExtensions.Humanize(str),
            onClick: () => props.onChange({ ...option, value: str }),
        }));
        input = (React.createElement(DropdownButton, { ...inputProps, columns: ['label'], items: options }, StringExtensions.Humanize(value)));
    }
    else {
        switch (option.kind) {
            case 'n':
                input = React.createElement(Input, { type: "number", onChange: handleInputChange, ...inputProps });
                break;
            case 's':
                input = React.createElement(Input, { type: "text", onChange: handleInputChange, ...inputProps });
                break;
            case 'b':
                input = (React.createElement(CheckBox, { onChange: handleCheckboxChange, checked: Boolean(value), type: "date" }, label));
                break;
        }
    }
    let content = (React.createElement(React.Fragment, null,
        React.createElement(Flex, { minWidth: LABEL_WIDTH, alignItems: "center" },
            label,
            " ",
            info),
        input));
    if (option.kind === 'b') {
        content = (React.createElement(Flex, { alignItems: "center" },
            input,
            " ",
            info));
    }
    return (React.createElement(Flex, { mb: 2, pl: 1 }, content));
};
const OptionsSection = (props) => {
    if (!props.options.length) {
        return React.createElement(React.Fragment, null);
    }
    return (React.createElement(Box, { mb: 2 },
        React.createElement(HelpBlock, { mb: 2 }, props.name ?? props.id),
        props.options.map((option, index) => (React.createElement(OptionInput, { key: index, option: option, onChange: props.onChange })))));
};
export const AdaptableOptionsForm = (props) => {
    const nocodeOptions = React.useMemo(() => {
        const metamodelService = new MetamodelService(() => props.adaptableOptions);
        return [...metamodelService.getGridInfoNoCodeOptions()];
    }, [props.adaptableOptions]);
    const handleOptionChange = (sectionName) => (option) => {
        const adaptableOptions = { ...props.adaptableOptions };
        if (sectionName === 'baseOptions') {
            // @ts-ignore
            adaptableOptions[option.name] = option.value;
        }
        else {
            // @ts-ignore
            adaptableOptions[sectionName] = {
                // @ts-ignore
                ...adaptableOptions[sectionName],
                [option.name]: option.value,
            };
        }
        props.onChangedAdaptableOptions(adaptableOptions);
    };
    return (React.createElement(Box, { p: 2 }, nocodeOptions.map(([sectionName, { containerLabel, items }]) => {
        return (React.createElement(OptionsSection, { onChange: handleOptionChange(sectionName), key: sectionName, id: sectionName, name: containerLabel, options: items }));
    })));
};
