import * as React from 'react';
import OverlayTrigger from '../../../components/OverlayTrigger';
import SimpleButton from '../../../components/SimpleButton';
import { useAdaptable } from '../../AdaptableContext';
import { AdaptableIconComponent } from '../AdaptableIconComponent';
import { ColumnFilterMenu } from './components/ColumnFilterMenu';
import { FloatingFilterInputList } from './components/FloatingFilterInputList';
import { isPredicateEmpty, qlPredicateToString } from './utils';
import { AG_GRID_GROUPED_COLUMN } from '../../../Utilities/Constants/GeneralConstants';
import { Box, Flex } from '../../../components/Flex';
export const FloatingFilter = (props) => {
    const adaptable = useAdaptable();
    /**
     * We always have a syntetic predicate with AND or OR, so the logic is easyer.
     * The wrapper is in charge of constructing the correct column filter.
     */
    const isMultiple = props.predicate?.args?.length > 1;
    const isManualApply = adaptable.api.filterApi.columnFilterApi.internalApi.shouldManuallyApplyColumnFilter(props.columnId);
    const isInlineEditable = !isMultiple && !isManualApply;
    // only used when there is only one filter selected
    let singleFilterPredicateDef = null;
    if (props.predicate.args.length === 1) {
        singleFilterPredicateDef = props.predicateDefs.find((predicateDef) => predicateDef.operator === props.predicate.args[0].operator);
    }
    const noInputs = !singleFilterPredicateDef?.inputs || singleFilterPredicateDef.inputs.length === 0;
    let showLabel = isMultiple || noInputs || isManualApply;
    if (props.columnId === AG_GRID_GROUPED_COLUMN) {
        showLabel = false;
    }
    let label = qlPredicateToString(props.predicate, props.predicateDefs);
    if (isManualApply &&
        singleFilterPredicateDef &&
        isPredicateEmpty(props.predicate.args[0], singleFilterPredicateDef)) {
        label = '';
    }
    const showQuickFilterDropdown = adaptable.api.filterApi.columnFilterApi.internalApi.showQuickFilterDropdown(props.columnId);
    const handleClear = () => props.onClear?.();
    const showEvent = 'click';
    const hideEvent = 'blur';
    const [overlayVisible, setOverlayVisible] = React.useState(false);
    let filterDropdown = null;
    const filterDropdownButton = (React.createElement(SimpleButton, { variant: "text", "data-name": "floating-filter-button", onBlur: () => {
            if (isInlineEditable) {
                setOverlayVisible(false);
            }
        }, "data-value": props.predicate?.args[0]?.operator, onClick: () => {
            if (!isInlineEditable) {
                adaptable.api.filterApi.columnFilterApi.internalApi.openColumnFilterPopup(props.columnId);
            }
            else {
                setOverlayVisible(true);
            }
        }, style: {
            textAlign: 'left',
            marginRight: 1, // just so that the focus outline is not cut off
            ...(!isInlineEditable
                ? {
                    minWidth: 0,
                    flex: 1,
                }
                : {}),
        } },
        React.createElement(Box, null, !isManualApply && singleFilterPredicateDef?.icon ? (singleFilterPredicateDef?.icon) : (React.createElement(AdaptableIconComponent, { icon: { name: 'filter' } }))),
        showLabel && (React.createElement(Box, { className: "ab-FloatingFilter-label twa:ml-2 twa:flex-1", title: label }, label))));
    if (isInlineEditable) {
        filterDropdown = showQuickFilterDropdown && (React.createElement(OverlayTrigger, { className: "ab-FloatingFilter-overlay", showEvent: showEvent, hideEvent: hideEvent, visible: overlayVisible, onVisibleChange: setOverlayVisible, preventPortalEventPropagation: showEvent === 'click', targetOffset: 10, hideDelay: 50, "data-name": "floating-filter-overlay", render: () => {
                // we render this only for single filter
                return (React.createElement(ColumnFilterMenu, { columnId: props.columnId, disabled: props.disabled, predicate: props.predicate.args[0], predicateDefs: props.predicateDefs, onPredicateChange: (predicate) => {
                        setOverlayVisible(false);
                        props.onPredicateChange({
                            operator: props.predicate.operator,
                            args: [predicate],
                        });
                    } }));
            } }, filterDropdownButton));
    }
    else {
        filterDropdown = filterDropdownButton;
    }
    return (React.createElement(Flex, { className: "ab-FloatingFilter twa:w-full", onKeyDownCapture: (e) => {
            // AG Grid's header keyboard navigation intercepts Tab and calls preventDefault(),
            // which prevents focus from moving between elements inside the floating filter.
            // We handle Tab manually in the capture phase (before AG Grid's handlers).
            if (e.key === 'Tab') {
                const target = e.target;
                const wrapper = e.currentTarget;
                if (!e.shiftKey) {
                    // Tab forward: from filter button → select input
                    if (target.getAttribute('data-name') === 'floating-filter-button') {
                        const selectInput = wrapper.querySelector('[data-name="Select Values"] input');
                        if (selectInput) {
                            e.preventDefault();
                            e.nativeEvent.stopImmediatePropagation();
                            selectInput.focus();
                            // When the DummyInput gets focus, react-select sets isFocused=true,
                            // triggering a React re-render. During this re-render, unstable component
                            // references in selectComponents can cause the DummyInput to be removed
                            // from DOM and recreated, losing focus. We restore focus after the re-render.
                            requestAnimationFrame(() => {
                                if (document.activeElement === document.body || document.activeElement === null) {
                                    const newInput = wrapper.querySelector('[data-name="Select Values"] input');
                                    newInput?.focus();
                                }
                            });
                        }
                    }
                }
            }
        } },
        filterDropdown,
        isInlineEditable && (React.createElement(Flex, { className: "twa:flex-1 twa:min-w-0" },
            React.createElement(FloatingFilterInputList, { onKeyDown: props.onKeydown, columnId: props.columnId, disabled: props.disabled, 
                // It works only with a predicate
                predicate: props.predicate.args[0], predicateDefs: props.predicateDefs, onPredicateChange: (predicate) => {
                    props.onPredicateChange({
                        operator: props.predicate.operator,
                        args: [predicate],
                    });
                } }))),
        isInlineEditable && (React.createElement(SimpleButton, { className: "twa:px-0", onClick: () => {
                adaptable.api.filterApi.columnFilterApi.internalApi.openColumnFilterPopup(props.columnId, {
                    onChange: props.onChange,
                });
            }, "data-name": "expand-filter", icon: "expand", variant: "text" })),
        (isMultiple ||
            !isPredicateEmpty(props.predicate.args[0], singleFilterPredicateDef)) && (React.createElement(SimpleButton, { "data-name": "clear-filter", className: "twa:p-0", variant: "text", onClick: handleClear, icon: "close" }))));
};
