"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CombinatorSelector = exports.ExpressionSelector = exports.PrimitiveMultiValueInput = exports.PrimiteValueInput = exports.PrimitiveColumnOrFieldSelector = void 0;
const tslib_1 = require("tslib");
const react_1 = tslib_1.__importDefault(require("react"));
const rebass_1 = require("rebass");
const mapQlPredicateToExpression_1 = require("../../../parser/src/predicate/mapQlPredicateToExpression");
const adaptableQlUtils_1 = require("../../../Utilities/adaptableQlUtils");
const AdaptableContext_1 = require("../../../View/AdaptableContext");
const AdaptableInput_1 = tslib_1.__importDefault(require("../../../View/Components/AdaptableInput"));
const ColumnSelector_1 = require("../../../View/Components/Selectors/ColumnSelector");
const FieldSelector_1 = require("../../../View/Components/Selectors/FieldSelector");
const PermittedValuesSelector_1 = require("../../../View/Components/Selectors/PermittedValuesSelector");
const CheckBox_1 = require("../../CheckBox");
const DropdownButton_1 = tslib_1.__importDefault(require("../../DropdownButton"));
const icons_1 = require("../../icons");
const InputGroup_1 = require("../../InputGroup");
const Select_1 = require("../../Select");
const QueryBuilder_1 = require("./QueryBuilder");
const utils_1 = require("./utils");
const PrimitiveColumnOrFieldSelector = (props) => {
    const adaptable = (0, AdaptableContext_1.useAdaptable)();
    const [type, setType] = react_1.default.useState(() => {
        return (
            // default to column
            (!props.fieldOrColumn || props.fieldOrColumn.includes('[') ? 'column' : 'field')
        );
    });
    const hasFields = react_1.default.useMemo(() => {
        return adaptable.api.expressionApi.internalApi.getAvailableFields()?.length > 0;
    }, []);
    const hasFieldsOrValueIsField = hasFields || (0, utils_1.isFieldValue)(props.fieldOrColumn);
    let input = null;
    if (type === 'column') {
        const columnId = (0, utils_1.mapColumnExpressionToColumnId)(props.fieldOrColumn);
        input = (react_1.default.createElement(ColumnSelector_1.ColumnSelector, { value: columnId, type: props.type, onChange: (columnId) => {
                props.onChange(`[${columnId}]`);
            } }));
    }
    else {
        input = (react_1.default.createElement(FieldSelector_1.FieldSelector, { value: (0, utils_1.mapExpressionToFieldValue)(props.fieldOrColumn), type: props.type, onChange: (fieldValue) => {
                props.onChange((0, utils_1.mapFieldValueToExpression)(fieldValue));
            } }));
    }
    const typeOptions = [
        {
            label: (react_1.default.createElement(rebass_1.Flex, { alignItems: "center" },
                react_1.default.createElement(icons_1.Icon, { name: "grid" }),
                react_1.default.createElement(rebass_1.Text, { ml: 2 }, "Column"))),
            value: 'column',
            icon: 'grid',
        },
        {
            label: (react_1.default.createElement(rebass_1.Flex, { alignItems: "center" },
                react_1.default.createElement(icons_1.Icon, { name: "column-outline" }),
                react_1.default.createElement(rebass_1.Text, { ml: 2 }, "Field"))),
            value: 'field',
            icon: 'column-outline',
        },
    ];
    return !hasFieldsOrValueIsField || props.hideFields ? (react_1.default.createElement(rebass_1.Box, null, input)) : (react_1.default.createElement(InputGroup_1.InputGroup, { Component: rebass_1.Flex, "data-id": "query-first-arg-wrapper" },
        react_1.default.createElement(Select_1.Select, { renderSingleValue: (value) => {
                return react_1.default.createElement(react_1.default.Fragment, null, type === 'column' ? react_1.default.createElement(icons_1.Icon, { name: "grid" }) : react_1.default.createElement(icons_1.Icon, { name: "column-outline" }));
            }, value: type, options: typeOptions, onChange: (value) => {
                props.onChange(null);
                setType(value);
            } }),
        input));
};
exports.PrimitiveColumnOrFieldSelector = PrimitiveColumnOrFieldSelector;
const PrimiteValueInput = (props) => {
    const adaptable = (0, AdaptableContext_1.useAdaptable)();
    const hasFields = react_1.default.useMemo(() => {
        return adaptable.api.expressionApi.internalApi.getAvailableFields()?.length > 0;
    }, []);
    const hasFieldsOrValueIsField = hasFields || (0, utils_1.isFieldValue)(props.value);
    const [type, setType] = react_1.default.useState(() => {
        if (typeof props?.value === 'string' && props?.value?.includes('[')) {
            return 'column-name';
        }
        if (typeof props?.value === 'string' && props?.value?.includes('FIELD')) {
            return 'field';
        }
        return 'input-value';
    });
    const handleTypeChange = (newType) => {
        if (type !== newType) {
            // need to reset value
            props.onChange(undefined);
            setType(newType);
        }
    };
    const getEditor = () => {
        const common = {
            'data-id': 'query-input',
        };
        switch (props.inputType) {
            case 'boolean':
                return (react_1.default.createElement(CheckBox_1.CheckBox, { ...common, checked: props.value, onChange: () => props.onChange(!props.value) }));
            case 'number':
                return (react_1.default.createElement(AdaptableInput_1.default, { ...common, type: "number", value: props.value ?? '', onChange: (event) => {
                        const value = event.target.value;
                        if (value === '') {
                            props.onChange(undefined);
                        }
                        else {
                            props.onChange(parseFloat(value));
                        }
                    } }));
            case 'text':
                return (react_1.default.createElement(AdaptableInput_1.default, { ...common, type: "text", value: props.value ?? '', onChange: (event) => {
                        props.onChange(event.target.value);
                    } }));
            case 'date':
                // date format = 'DATE(2020-01-01)'
                const dateStr = typeof props.value === 'string' ? props.value.replace('DATE(', '').replace(')', '') : '';
                return (react_1.default.createElement(AdaptableInput_1.default, { ...common, type: "date", value: dateStr ?? '', onChange: (event) => {
                        const stringified = `DATE("${event.target.value}")`;
                        props.onChange(stringified);
                    } }));
            default:
                return react_1.default.createElement(react_1.default.Fragment, null);
        }
    };
    let editor = null;
    if (type === 'column-name') {
        const abColType = (0, adaptableQlUtils_1.mapExpressionFunctionTypeToColumnDataType)(props.inputType);
        editor = (react_1.default.createElement(exports.PrimitiveColumnOrFieldSelector, { hideFields: true, fieldOrColumn: props.value, type: abColType, onChange: (columnId) => {
                props.onChange(columnId);
            } }));
    }
    else if (type === 'field') {
        editor = (react_1.default.createElement(FieldSelector_1.FieldSelector, { value: (0, utils_1.mapExpressionToFieldValue)(props.value), onChange: (fieldValue) => {
                props.onChange((0, utils_1.mapFieldValueToExpression)(fieldValue));
            } }));
    }
    else if (!['date', 'boolean'].includes(props.inputType)) {
        editor = (react_1.default.createElement(PermittedValuesSelector_1.PermittedValuesSelector, { allowNewValues: true, value: props.value, columnId: (0, utils_1.mapColumnExpressionToColumnId)(props.lefthandColumnIdParam), onChange: (value) => {
                props.onChange(value);
            } }));
    }
    else {
        editor = getEditor();
    }
    const options = [
        {
            label: (react_1.default.createElement(rebass_1.Flex, { alignItems: "center" },
                react_1.default.createElement(icons_1.Icon, { name: "columns" }),
                react_1.default.createElement(rebass_1.Text, { ml: 2 }, "Column"))),
            icon: 'columns',
            value: 'column-name',
        },
        {
            label: (react_1.default.createElement(rebass_1.Flex, { alignItems: "center" },
                react_1.default.createElement(icons_1.Icon, { name: "edit" }),
                react_1.default.createElement(rebass_1.Text, { ml: 2 }, "Value"))),
            icon: 'edit',
            value: 'input-value',
        },
    ];
    if (hasFieldsOrValueIsField || type === 'field') {
        options.push({
            label: (react_1.default.createElement(rebass_1.Flex, { alignItems: "center" },
                react_1.default.createElement(icons_1.Icon, { name: "column-outline" }),
                react_1.default.createElement(rebass_1.Text, { ml: 2 }, "Field"))),
            icon: 'column-outline',
            value: 'field',
        });
    }
    const typeOption = options.find((option) => option.value === type);
    return (react_1.default.createElement(InputGroup_1.InputGroup, { Component: rebass_1.Flex, "data-id": "query-input-wrapper", mr: 2 },
        react_1.default.createElement(Select_1.Select, { renderSingleValue: (value) => {
                return (react_1.default.createElement(react_1.default.Fragment, null, typeOption.value === 'column-name' ? react_1.default.createElement(icons_1.Icon, { name: "grid" }) : react_1.default.createElement(icons_1.Icon, { name: "edit" })));
            }, value: typeOption.value, options: options, onChange: (value) => handleTypeChange(value) }),
        editor));
};
exports.PrimiteValueInput = PrimiteValueInput;
const PrimitiveMultiValueInput = (props) => {
    return (react_1.default.createElement(PermittedValuesSelector_1.PermittedValuesSelector, { isMulti: true, allowNewValues: true, value: props.value, columnId: (0, utils_1.mapColumnExpressionToColumnId)(props.lefthandColumnIdParam), onChange: (value) => {
            props.onChange(value);
        } }));
};
exports.PrimitiveMultiValueInput = PrimitiveMultiValueInput;
const SymbolToIcon = (props) => {
    switch (props.symbol) {
        case '=':
            return react_1.default.createElement(icons_1.Icon, { name: "equals" });
        case '!=':
            return react_1.default.createElement(icons_1.Icon, { name: "not-equal" });
        case '>':
            return react_1.default.createElement(icons_1.Icon, { name: "greater-than" });
        case '>=':
            return react_1.default.createElement(icons_1.Icon, { name: "greater-than-or-equal" });
        case '<':
            return react_1.default.createElement(icons_1.Icon, { name: "less-than" });
        case '<=':
            return react_1.default.createElement(icons_1.Icon, { name: "less-than-or-equal" });
        default:
            return react_1.default.createElement(react_1.default.Fragment, null, props.symbol);
    }
};
const ExpressionSelector = (props) => {
    const { getExpressions } = (0, QueryBuilder_1.useQueryBuilderContext)();
    const expressions = props.dataType ? getExpressions(props.dataType) : [];
    return (react_1.default.createElement(DropdownButton_1.default, { "data-id": "expression-selector", "data-value": props.value, variant: "raised", tone: 'accent', columns: ['label'], items: expressions.map((expression) => ({
            label: react_1.default.createElement(SymbolToIcon, { symbol: (0, mapQlPredicateToExpression_1.getQlPredicateSymbol)(expression) }),
            onClick: () => {
                if (expression !== props.value) {
                    props.onExpressionChange(expression);
                }
            },
        })) },
        react_1.default.createElement(SymbolToIcon, { symbol: (0, mapQlPredicateToExpression_1.getQlPredicateSymbol)(props.value) ?? 'Select Operator' })));
};
exports.ExpressionSelector = ExpressionSelector;
const CombinatorSelector = (props) => {
    return (react_1.default.createElement(DropdownButton_1.default, { "data-id": "combinator-selector", "data-value": props.value, columns: ['label'], variant: "raised", tone: "accent", items: [
            { label: 'AND', onClick: () => props.onChange('AND') },
            { label: 'OR', onClick: () => props.onChange('OR') },
        ] }, props.value));
};
exports.CombinatorSelector = CombinatorSelector;
