import * as React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import * as InternalRedux from '../../Redux/ActionsReducers/InternalRedux';
import { GridFilterModuleId, NamedQueryModuleId } from '../../Utilities/Constants/ModuleConstants';
import StringExtensions from '../../Utilities/Extensions/StringExtensions';
import { useAdaptable } from '../AdaptableContext';
import * as PopupRedux from '../../Redux/ActionsReducers/PopupRedux';
export const useGridFilterExpressionEditor = () => {
    const adaptable = useAdaptable();
    const dispatch = useDispatch();
    const currentLayout = useSelector((state) => {
        return state.Layout.Layouts.find((l) => l.Name == state.Layout.CurrentLayout);
    });
    const isReadOnly = Boolean(currentLayout?.IsReadOnly);
    const gridFilter = currentLayout?.GridFilter;
    const [isAdaptableReady, setIsAdaptableReady] = React.useState(false);
    const [expression, setExpression] = React.useState(() => {
        return adaptable.api.filterApi.gridFilterApi.getCurrentGridFilterExpression();
    });
    const namedQueries = useSelector((state) => state.NamedQuery.NamedQueries) ?? [];
    const cachedQueries = useSelector((state) => state.Internal.CachedQueries) ?? [];
    const isSuspended = gridFilter?.IsSuspended ?? false;
    const onAddCachedQuery = (cachedQuery) => {
        dispatch(InternalRedux.CachedQueryAdd(cachedQuery));
    };
    const gridFilterHelpPage = adaptable.ModuleService.getModuleById('GridFilter').moduleInfo.HelpPage;
    const gridFilterLinkDisabled = !adaptable.api.internalApi.isDocumentationLinksDisplayed();
    React.useEffect(() => {
        adaptable.api.eventApi.on('AdaptableReady', () => {
            setIsAdaptableReady(true);
        });
    }, []);
    React.useEffect(() => {
        if (gridFilter?.Expression != expression) {
            setExpression(gridFilter?.Expression ?? '');
        }
    }, [gridFilter?.Expression]);
    const isExpressionValid = expression == '' ||
        adaptable.api.internalApi
            .getQueryLanguageService()
            .validateBoolean(expression, NamedQueryModuleId).isValid;
    const isExpressionNamedQuery = namedQueries.find((sq) => sq.BooleanExpression == expression) != null;
    const availableColumns = adaptable.api.columnApi.getColumns().map((col) => {
        return {
            columnId: col.columnId,
            label: col.friendlyName,
            onClick: () => {
                // Bogdan - im sure there is a better way to do this check with fancy operators i dont know
                const newExp = StringExtensions.IsNotNullOrEmpty(expression) ? expression : '';
                setExpression(newExp + `[${col.columnId}]`);
            },
        };
    });
    const clearQuery = () => {
        adaptable.api.filterApi.gridFilterApi.clearGridFilter();
        setExpression('');
    };
    const runQuery = (newExpression = expression) => {
        if (StringExtensions.IsNullOrEmpty(newExpression) &&
            StringExtensions.IsNotNullOrEmpty(gridFilter?.Expression)) {
            // user pressed enter key with an empty input => clear existing expression
            adaptable.api.filterApi.gridFilterApi.setGridFilterExpression('');
            return;
        }
        if (!adaptable.api.internalApi
            .getQueryLanguageService()
            .validateBoolean(newExpression, NamedQueryModuleId).isValid) {
            return;
        }
        if (StringExtensions.IsNotNullOrEmpty(expression)) {
            let cachedQuery = {
                expression: expression,
                time: new Date(),
            };
            if (cachedQuery) {
                onAddCachedQuery(cachedQuery);
            }
        }
        adaptable.api.filterApi.gridFilterApi.setGridFilterExpression(newExpression);
    };
    const gridFilterAccessLevel = React.useMemo(() => {
        return adaptable.api.entitlementApi.getEntitlementAccessLevelForModule(GridFilterModuleId);
    }, []);
    const namedQueryModuleAccessLevel = adaptable.api.entitlementApi.getEntitlementAccessLevelForModule(NamedQueryModuleId);
    const onShowNamedQueries = (value, popup) => dispatch(PopupRedux.PopupShowScreen(NamedQueryModuleId, popup, {
        action: 'New',
        source: 'Other',
        value,
    }));
    const saveQuery = () => {
        const namedqueryPopuName = adaptable.api.internalApi
            .getModuleService()
            .getModuleById(NamedQueryModuleId).moduleInfo.Popup;
        onShowNamedQueries(expression, namedqueryPopuName);
    };
    const suspendGridFilter = () => {
        adaptable.api.filterApi.gridFilterApi.suspendGridFilter();
    };
    const unSuspendGridFilter = () => {
        adaptable.api.filterApi.gridFilterApi.unSuspendGridFilter();
    };
    return {
        isReadOnly,
        namedQueryModuleAccessLevel,
        cachedQueries,
        expression,
        setExpression,
        isExpressionNamedQuery,
        isExpressionValid,
        isSuspended,
        gridFilter,
        isAdaptableReady,
        namedQueries,
        onAddCachedQuery,
        availableColumns,
        runQuery,
        clearQuery,
        onExpand: () => adaptable.api.filterApi.gridFilterApi.openUIEditorForGridFilter(expression),
        saveQuery,
        suspendGridFilter,
        unSuspendGridFilter,
        setGridFilterExpression: (expression) => {
            adaptable.api.filterApi.gridFilterApi.setGridFilterExpression(expression);
        },
        gridFilterAccessLevel,
        gridFilterHelpPage,
        gridFilterLinkDisabled,
    };
};
