import * as React from 'react';
import { Box, Flex } from 'rebass';
import SimpleButton from '../../../components/SimpleButton';
import { ColumnFilterInputList } from './components/ColumnFilterInputList';
import { usePredicateDef } from './hooks';
import Radio from '../../../components/Radio';
import { useAdaptable } from '../../AdaptableContext';
import { Select } from '../../../components/Select';
import { mapQlPredicateToAdaptablePredicate } from './utils';
const ColumnFilterPredicateDropdown = (props) => {
    const predicateDef = usePredicateDef(props.predicate?.operator, props.predicateDefs);
    const options = props.predicateDefs.map((predicateDef) => {
        return {
            label: (React.createElement(Box, { display: 'flex', alignItems: "center" },
                React.createElement(SimpleButton, { variant: "raised", 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(Box, { display: 'flex', alignItems: "center", className: "ab-ColumnFilterPredicateDropdown", style: {
            //@ts-ignore ignore
            '--ab-cmp-input__background': 'var(--ab-color-primary)',
        } },
        React.createElement(Select, { style: predicateDef
                ? {
                    minWidth: '10rem',
                }
                : null // for AND and OR don't apply a min width
            , onChange: (value) => {
                props.onPredicateChange({
                    operator: value,
                    args: [],
                });
            }, options: options, value: isAndOr ? 'Add Condition' : props.predicate?.operator })));
};
const ColumnFilterEditor = (props) => {
    return (React.createElement(Box, { mb: 3 },
        React.createElement(Flex, { mb: 2 },
            React.createElement(ColumnFilterPredicateDropdown, { columnId: props.columnId, disabled: props.disabled, predicate: props.predicate, predicateDefs: props.predicateDefs, onPredicateChange: props.onPredicateChange }),
            React.createElement(Flex, { alignItems: "center", ml: 2 },
                React.createElement(SimpleButton, { disabled: props.deleteDisabled, onClick: props.onDelete, variant: "text", icon: "delete" }))),
        React.createElement(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,
            { flex: 1 },
            React.createElement(Radio, { mr: 2, onClick: () => props.onChange('AND'), checked: props.operator === 'AND' }, "AND"),
            React.createElement(Radio, { mr: 2, onClick: () => props.onChange('OR'), checked: props.operator === 'OR' }, "OR")
        ))
    );
};
export const ColumnFilterComponent = (props) => {
    const adaptable = 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) => mapQlPredicateToAdaptablePredicate(qlPredicate))
            .some((adaptablePredicate) => adaptable.api.predicateApi.isValidPredicate(adaptablePredicate));
    };
    return (React.createElement(React.Fragment, null,
        React.createElement(Flex, { flexDirection: "column", backgroundColor: "primarylight", pb: !props.hideActionButtons ? 2 : undefined, mb: props.location === 'filterForm' ? 2 : undefined, mt: props.location === 'columnMenu' ? 2 : undefined, ml: props.location === 'columnMenu' ? 2 : undefined, mr: props.location === 'columnMenu' ? 2 : undefined, style: { borderRadius: 'var(--ab__border-radius)' } },
            React.createElement(Flex, { m: 2 },
                React.createElement(AndOrInput, { onChange: onCombineChange, operator: currentPredicate.operator })),
            !props.hideActionButtons && (React.createElement(Flex, { ml: 2, mr: 2, className: "ab-ColumnFilter-actions", justifyContent: "space-between" },
                React.createElement(Box, { className: "ab-ColumnFilter-action-clearall" },
                    React.createElement(SimpleButton, { "aria-label": 'Clear All Filters', onClick: () => clearAllFilters() }, "Clear All")),
                manuallyApplyColumnFilter ? (React.createElement(React.Fragment, null,
                    React.createElement(Box, { flex: 1, "data-name": "spacer" }),
                    React.createElement(Box, { className: "ab-ColumnFilter-action-reset", mr: 2 },
                        React.createElement(SimpleButton, { "aria-label": 'Reset All', tone: "neutral", variant: "raised", onClick: () => {
                                setPredicateNotYetApplied(props.predicate);
                            } }, "Reset")),
                    React.createElement(Box, { className: "ab-ColumnFilter-action-apply" },
                        React.createElement(SimpleButton, { "aria-label": 'Apply Filter', tone: "accent", variant: "raised", onClick: applyFilter, disabled: !isAtLeastOneColumnFilterValid(predicateNotYetApplied?.args) && !isAtLeastOneColumnFilterValid(currentPredicate.args) }, "Apply")))) : null))),
        React.createElement(Flex, { flexDirection: "column", className: "ab-ColumnFilter", flex: 1, minHeight: 0, ...props.wrapperProps },
            React.createElement(Box, { style: { 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))));
};
