import React from 'react';
import { isAdaptableIcon } from '../../../components/Icon';
import { AdaptableIconComponent } from '../AdaptableIconComponent';
export const mapAdaptablePredicateDefToQlPredicateDef = (adaptablePredicateDef, 
// used to determine values type
dataType) => {
    let icon = null;
    if (isAdaptableIcon(adaptablePredicateDef.icon)) {
        icon = React.createElement(AdaptableIconComponent, { icon: adaptablePredicateDef.icon });
    }
    else if (adaptablePredicateDef.icon && 'text' in adaptablePredicateDef.icon) {
        icon = React.createElement('div', { children: adaptablePredicateDef.icon.text });
    }
    const inputs = (adaptablePredicateDef?.inputs ?? [])?.map((input) => {
        return input.type;
    });
    if ((adaptablePredicateDef.id === 'In' || adaptablePredicateDef.id === 'NotIn') &&
        ['text', 'number', 'date'].includes(dataType)) {
        // add array type
        inputs.push(`${dataType}[]`);
    }
    const qlPredicateDef = {
        operator: adaptablePredicateDef.id,
        label: adaptablePredicateDef.label ?? adaptablePredicateDef.id,
        icon,
        inputs,
        toString: (params) => adaptablePredicateDef.label,
    };
    if (adaptablePredicateDef.hasOwnProperty('toString')) {
        qlPredicateDef.toString = adaptablePredicateDef.toString;
    }
    return qlPredicateDef;
};
export const mapAdaptablePredicateToQlPredicate = (adaptablePredicate) => {
    return {
        operator: adaptablePredicate.PredicateId, // make sure all predicates are in qal
        args: adaptablePredicate.Inputs,
    };
};
export const mapQlPredicateToAdaptablePredicate = (qlPredicate) => {
    return {
        PredicateId: qlPredicate.operator,
        Inputs: qlPredicate.args,
    };
};
export const qlPredicateToString = (qlPredicate, predicateDefs) => {
    if (typeof qlPredicate === 'object' &&
        'operator' in qlPredicate &&
        (qlPredicate.operator === 'AND' || qlPredicate.operator === 'OR')) {
        // save to join args because there is no extra nesting
        return qlPredicate.args
            .filter((str) => str)
            .map((arg) => qlPredicateToString(arg, predicateDefs))
            .join(` ${qlPredicate.operator} `);
    }
    const predicateDef = predicateDefs.find((predicateDef) => predicateDef.operator === qlPredicate.operator);
    if (!predicateDef) {
        return qlPredicate.operator;
    }
    if (!predicateDef) {
        return qlPredicate.operator;
    }
    if (!predicateDef.hasOwnProperty('toString')) {
        return predicateDef.label;
    }
    const str = predicateDef.toString({
        inputs: (qlPredicate.args || []).filter((arg) => arg != undefined),
    });
    return str;
};
export const isPredicateEmpty = (predicate, predicateDef) => {
    if (!predicateDef?.inputs || predicateDef.inputs.length === 0) {
        return false;
    }
    return (!predicate ||
        !predicate.args ||
        predicate.args.length === 0 ||
        predicate.args.every((arg) => arg == undefined));
};
export const mapColumnFilterToQlPredicate = (columnFilter, abColumn, qlPredicateDefs, columnFilterOptions, api) => {
    const combinator = columnFilter?.PredicatesOperator ?? 'AND';
    const qlPredicate = {
        operator: combinator,
        args: (columnFilter?.Predicates ?? []).map?.(mapAdaptablePredicateToQlPredicate),
    };
    if (qlPredicate.args.length === 0) {
        // used when none is defined
        let defaultQlPredicate = null;
        switch (abColumn.dataType) {
            case 'number':
                let defaultQlNumberPredicate;
                const defaultNumericColumnFilter = columnFilterOptions.defaultNumericColumnFilter;
                if (defaultNumericColumnFilter) {
                    if (typeof defaultNumericColumnFilter === 'function') {
                        const context = {
                            column: abColumn,
                            ...api.internalApi.buildBaseContext(),
                        };
                        defaultQlNumberPredicate = defaultNumericColumnFilter(context);
                    }
                    else {
                        defaultQlNumberPredicate = defaultNumericColumnFilter;
                    }
                }
                defaultQlPredicate = defaultQlNumberPredicate
                    ? { operator: defaultQlNumberPredicate, args: [] }
                    : { operator: 'Equals', args: [] };
                break;
            case 'text':
                let defaultQlTextPredicate;
                const defaultTextColumnFilter = columnFilterOptions.defaultTextColumnFilter;
                if (defaultTextColumnFilter) {
                    if (typeof defaultTextColumnFilter === 'function') {
                        const context = {
                            column: abColumn,
                            ...api.internalApi.buildBaseContext(),
                        };
                        defaultQlTextPredicate = defaultTextColumnFilter(context);
                    }
                    else {
                        defaultQlTextPredicate = defaultTextColumnFilter;
                    }
                }
                defaultQlPredicate = defaultQlTextPredicate
                    ? { operator: defaultQlTextPredicate, args: [] }
                    : { operator: 'Contains', args: [] };
                break;
            case 'date':
                let defaultQlDatePredicate;
                const defaultDateColumnFilter = columnFilterOptions.defaultDateColumnFilter;
                if (defaultDateColumnFilter) {
                    if (typeof defaultDateColumnFilter === 'function') {
                        const context = {
                            column: abColumn,
                            ...api.internalApi.buildBaseContext(),
                        };
                        defaultQlDatePredicate = defaultDateColumnFilter(context);
                    }
                    else {
                        defaultQlDatePredicate = defaultDateColumnFilter;
                    }
                }
                defaultQlPredicate = defaultQlDatePredicate
                    ? { operator: defaultQlDatePredicate, args: [] }
                    : { operator: 'On', args: [] };
                break;
            case 'boolean':
                defaultQlPredicate = { operator: 'BooleanToggle', args: [] };
                break;
        }
        if (defaultQlPredicate === null) {
            // take the firstavailable one
            if (qlPredicateDefs.length > 0) {
                defaultQlPredicate = { operator: qlPredicateDefs[0].operator, args: [] };
            }
        }
        if (defaultQlPredicate) {
            qlPredicate.args = [defaultQlPredicate];
        }
    }
    return qlPredicate;
};
