"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ColumnFilterComponent = void 0;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const SimpleButton_1 = tslib_1.__importDefault(require("../../../components/SimpleButton"));
const ColumnFilterInputList_1 = require("./components/ColumnFilterInputList");
const hooks_1 = require("./hooks");
const Radio_1 = tslib_1.__importDefault(require("../../../components/Radio"));
const AdaptableContext_1 = require("../../AdaptableContext");
const Select_1 = require("../../../components/Select");
const utils_1 = require("./utils");
const Flex_1 = require("../../../components/Flex");
const clsx_1 = tslib_1.__importDefault(require("clsx"));
const twMerge_1 = require("../../../twMerge");
const ColumnFilterPredicateDropdown = (props) => {
    const predicateDef = (0, hooks_1.usePredicateDef)(props.predicate?.operator, props.predicateDefs);
    const options = props.predicateDefs.map((predicateDef) => {
        return {
            label: (React.createElement(Flex_1.Box, { className: "twa:flex twa:items-center" },
                React.createElement(SimpleButton_1.default, { variant: "raised", className: "twa:mr-2", tone: "accent" }, predicateDef.icon),
                predicateDef.label)),
            value: predicateDef.operator,
        };
    });
    const operator = props.predicate?.operator;
    const isAndOr = operator === 'AND' || operator === 'OR';
    return (React.createElement(Flex_1.Box, { className: "twa:flex twa:items-center ab-ColumnFilterPredicateDropdown", style: {
            //@ts-ignore ignore
            '--ab-cmp-input__background': 'var(--ab-color-primary)',
        } },
        React.createElement(Select_1.Select, { className: predicateDef ? `twa:min-w-[10rem]` : null, onChange: (value) => {
                props.onPredicateChange({
                    operator: value,
                    args: [],
                });
            }, options: options, value: isAndOr ? 'Add Condition' : props.predicate?.operator })));
};
const ColumnFilterEditor = (props) => {
    return (React.createElement(Flex_1.Box, { className: "twa:mb-3" },
        React.createElement(Flex_1.Flex, { className: "twa:mb-2" },
            React.createElement(ColumnFilterPredicateDropdown, { columnId: props.columnId, disabled: props.disabled, predicate: props.predicate, predicateDefs: props.predicateDefs, onPredicateChange: props.onPredicateChange }),
            React.createElement(Flex_1.Flex, { alignItems: "center", className: "twa:ml-2" },
                React.createElement(SimpleButton_1.default, { disabled: props.deleteDisabled, onClick: props.onDelete, variant: "text", icon: "delete" }))),
        React.createElement(ColumnFilterInputList_1.ColumnFilterInputList, { columnId: props.columnId, disabled: props.disabled, predicate: props.predicate, onPredicateChange: props.onPredicateChange, predicateDefs: props.predicateDefs })));
};
const AndOrInput = (props) => {
    return (
        // <Select
        //   value={props.operator}
        //   onChange={props.onChange}
        //   options={[
        //     { label: 'AND', value: 'AND' },
        //     { label: 'OR', value: 'OR' },
        //   ]}
        // />
        (React.createElement(
            Flex_1.Flex,
            { className: "twa:flex-1" },
            React.createElement(Radio_1.default, { className: "twa:mr-2", onClick: () => props.onChange('AND'), checked: props.operator === 'AND' }, "AND"),
            React.createElement(Radio_1.default, { className: "twa:mr-2", onClick: () => props.onChange('OR'), checked: props.operator === 'OR' }, "OR")
        ))
    );
};
const ColumnFilterComponent = (props) => {
    const adaptable = (0, AdaptableContext_1.useAdaptable)();
    const manuallyApplyColumnFilter = adaptable.api.filterApi.columnFilterApi.internalApi.shouldManuallyApplyColumnFilter(props.columnId);
    const [predicateNotYetApplied, setPredicateNotYetApplied] = React.useState(props.predicate);
    const applyFilter = () => {
        props.onPredicateChange(currentPredicateRef.current);
        setPredicateNotYetApplied(undefined);
    };
    const onPredicateChange = (predicate) => {
        // even if manuallyApplyColumnFilter is false, when we explicitly clear the filter
        // we want to apply the filter immediately
        if (!manuallyApplyColumnFilter || !predicate) {
            props.onPredicateChange(predicate);
        }
        else {
            setPredicateNotYetApplied(predicate);
        }
    };
    const clearAllFilters = () => {
        props.onPredicateChange(null);
        setPredicateNotYetApplied(undefined);
    };
    const onNewPredicate = (predicateDef) => {
        const currentPredicate = currentPredicateRef.current;
        const newPredicate = {
            ...currentPredicate,
            // @ts-ignore
            args: [...currentPredicate.args, { operator: predicateDef.operator, args: [] }],
        };
        onPredicateChange(newPredicate);
    };
    const onCombineChange = (operator) => {
        const newPredicate = {
            ...currentPredicateRef.current,
            args: currentPredicateRef.current.args || [],
            operator,
        };
        onPredicateChange(newPredicate);
    };
    const currentPredicate = !manuallyApplyColumnFilter
        ? props.predicate
        : predicateNotYetApplied ?? props.predicate;
    const currentPredicateRef = React.useRef(currentPredicate);
    //#ref-predicate
    currentPredicateRef.current = currentPredicate;
    // Not sure how to check this but would be nice...
    const isLastPredicateValid = true;
    const filterPredicateDropdown = (React.createElement(ColumnFilterPredicateDropdown, { columnId: props.columnId, disabled: props.disabled, predicate: currentPredicate, predicateDefs: props.predicateDefs, onPredicateChange: (predicate) => {
            const predicateDef = props.predicateDefs.find((predicateDef) => predicateDef.operator === predicate.operator);
            onNewPredicate(predicateDef);
        }, targetProps: {
            tone: 'neutral',
            variant: 'raised',
            children: 'Add Condition',
        } }));
    const isAtLeastOneColumnFilterValid = (qlPredicates) => {
        if (!qlPredicates?.length) {
            return false;
        }
        return qlPredicates
            .map((qlPredicate) => (0, utils_1.mapQlPredicateToAdaptablePredicate)(qlPredicate))
            .some((adaptablePredicate) => adaptable.api.predicateApi.isValidPredicate(adaptablePredicate));
    };
    return (React.createElement(React.Fragment, null,
        React.createElement(Flex_1.Flex, { flexDirection: "column", className: (0, clsx_1.default)({
                'twa:bg-primarylight': true,
                'twa:pb-2': !props.hideActionButtons,
                'twa:mb-2': props.location === 'filterForm',
                'twa:mt-2 twa:ml-2 twa:mr-2': props.location === 'columnMenu',
                'twa:rounded-standard': true,
            }) },
            React.createElement(Flex_1.Flex, { className: "twa:m-2" },
                React.createElement(AndOrInput, { onChange: onCombineChange, operator: currentPredicate.operator })),
            !props.hideActionButtons && (React.createElement(Flex_1.Flex, { className: "ab-ColumnFilter-actions twa:ml-2 twa:mr-2", justifyContent: "space-between" },
                React.createElement(Flex_1.Box, { className: "ab-ColumnFilter-action-clearall" },
                    React.createElement(SimpleButton_1.default, { "aria-label": 'Clear All Filters', onClick: () => clearAllFilters() }, "Clear All")),
                manuallyApplyColumnFilter ? (React.createElement(React.Fragment, null,
                    React.createElement(Flex_1.Box, { className: "twa:flex-1", "data-name": "spacer" }),
                    React.createElement(Flex_1.Box, { className: "ab-ColumnFilter-action-reset twa:mr-2" },
                        React.createElement(SimpleButton_1.default, { "aria-label": 'Reset All', tone: "neutral", variant: "raised", onClick: () => {
                                setPredicateNotYetApplied(props.predicate);
                            } }, "Reset")),
                    React.createElement(Flex_1.Box, { className: "ab-ColumnFilter-action-apply" },
                        React.createElement(SimpleButton_1.default, { "aria-label": 'Apply Filter', tone: "accent", variant: "raised", onClick: applyFilter, disabled: !isAtLeastOneColumnFilterValid(predicateNotYetApplied?.args) && !isAtLeastOneColumnFilterValid(currentPredicate.args) }, "Apply")))) : null))),
        React.createElement(Flex_1.Flex, { flexDirection: "column", style: props.wrapperProps?.style, className: (0, twMerge_1.twMerge)(`ab-ColumnFilter twa:flex-1 twa:min-h-0`, props.wrapperProps?.className) },
            React.createElement(Flex_1.Box, { className: "ab-ColumnFilter-content twa:overflow-auto" },
                currentPredicate.args.map((predicate, index) => {
                    return (React.createElement(ColumnFilterEditor, { deleteDisabled: currentPredicate.args.length < 2, onDelete: () => {
                            const currentPredicate = currentPredicateRef.current;
                            const newArgs = [...currentPredicate.args];
                            newArgs.splice(index, 1);
                            onPredicateChange({
                                operator: currentPredicate.operator,
                                args: newArgs,
                            });
                        }, key: index, columnId: props.columnId, disabled: props.disabled, predicate: predicate, predicateDefs: props.predicateDefs, onPredicateChange: (predicate) => {
                            // #ref-predicate - for whatever reason
                            // the `currentPredicate` here would be one from an old render
                            // if we weren't using a ref. we're not using memo/usecallback here,
                            // so I don't understand why this is happening
                            const currentPredicate = currentPredicateRef.current;
                            const newArgs = [...currentPredicate.args];
                            newArgs[index] = predicate;
                            onPredicateChange({
                                operator: currentPredicate.operator,
                                args: newArgs,
                            });
                        } }));
                }),
                isLastPredicateValid && filterPredicateDropdown))));
};
exports.ColumnFilterComponent = ColumnFilterComponent;
