"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EntityRulesEditor = exports.EntityRulesSummary = void 0;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const react_1 = require("react");
const rebass_1 = require("rebass");
const Tabs_1 = require("../../../components/Tabs");
const Radio_1 = tslib_1.__importDefault(require("../../../components/Radio"));
const ExpressionEditor_1 = require("../../../components/ExpressionEditor");
const AdaptableContext_1 = require("../../AdaptableContext");
const EntityRulePredicatesEditor_1 = require("./EntityRulePredicatesEditor");
const Panel_1 = tslib_1.__importDefault(require("../../../components/Panel"));
const QueryTab = (props) => {
    const { type, label, disabled = false } = props, tabProps = tslib_1.__rest(props, ["type", "label", "disabled"]);
    const text = (React.createElement(rebass_1.Flex, { flexDirection: "column" },
        label,
        " ",
        React.createElement(rebass_1.Text, { fontSize: 2 }, "query")));
    return (React.createElement(Tabs_1.Tabs.Tab, Object.assign({ style: { flex: 1 } }, tabProps), !disabled && props.showRadio ? (React.createElement(Radio_1.default, { tabIndex: -1, margin: 0, checked: type === props.value, style: { alignItems: 'baseline' } }, text)) : (text)));
};
// needed here to be considered a child Tab component, inside the Tabs component
Tabs_1.SupportedTabMenuComps.add(QueryTab);
const EntityRulesSummary = (props) => {
    var _a, _b, _c, _d, _e, _f, _g, _h;
    const { data } = props;
    const { api: { predicateApi, internalApi }, } = (0, AdaptableContext_1.useAdaptable)();
    if (!((_b = (_a = data === null || data === void 0 ? void 0 : data.Rule) === null || _a === void 0 ? void 0 : _a.Predicates) === null || _b === void 0 ? void 0 : _b.length) &&
        !((_c = data === null || data === void 0 ? void 0 : data.Rule) === null || _c === void 0 ? void 0 : _c.BooleanExpression) &&
        !((_d = data === null || data === void 0 ? void 0 : data.Rule) === null || _d === void 0 ? void 0 : _d.ObservableExpression) &&
        !((_e = data === null || data === void 0 ? void 0 : data.Rule) === null || _e === void 0 ? void 0 : _e.AggregatedBooleanExpression)) {
        return React.createElement(rebass_1.Text, { fontSize: 2 }, "No Rule defined");
    }
    return (React.createElement(
        rebass_1.Text,
        { fontSize: 2 },
        data.Rule.Predicates ? (React.createElement(React.Fragment, null, (_h = (_g = (_f = data.Rule) === null || _f === void 0 ? void 0 : _f.Predicates) === null || _g === void 0 ? void 0 : _g.map) === null || _h === void 0 ? void 0 : _h.call(_g, (predicate, index) => (
        // predicate id is not unique
        (React.createElement(
            React.Fragment,
            { key: index },
            props.renderPredicate(predicateApi.predicateToString(predicate))
        )))))) : (React.createElement(React.Fragment, null, props.renderQueryExpression(internalApi.getAdaptableQueryExpressionText(data.Rule))))
    ));
};
exports.EntityRulesSummary = EntityRulesSummary;
const RuleTabTitle = (props) => {
    return props.showRadio ? (React.createElement(Radio_1.default, { tabIndex: -1, margin: 0, checked: props.checked }, props.children)) : (React.createElement(React.Fragment, null, "props.children"));
};
const EntityRulesEditor = (props) => {
    var _a, _b;
    const { data, children, descriptions, predicateDefs, showNoRule = false, showPredicate = true, showObservable = true, showBoolean = true, showAggregation = true, flexProps, module, } = props;
    const { api } = (0, AdaptableContext_1.useAdaptable)();
    const numberOfTabs = [
        showNoRule,
        showPredicate,
        showObservable,
        showBoolean,
        showAggregation,
    ].filter(Boolean).length;
    const showRadioButtons = numberOfTabs > 1;
    const type = data.Rule == undefined
        ? 'NoRule'
        : data.Rule.BooleanExpression != undefined
            ? 'BooleanExpression'
            : data.Rule.ObservableExpression != undefined && showObservable
                ? 'ObservableExpression'
                : data.Rule.AggregatedBooleanExpression != undefined && showAggregation
                    ? 'AggregatedBooleanExpression'
                    : 'Predicate';
    const [selectedTab, setSelectedTab] = React.useState(type);
    const setType = (type) => {
        setSelectedTab(type);
        if (type === 'NoRule' && showNoRule) {
            delete data.Rule;
            props.onChange(Object.assign({}, data));
        }
        else if (type === 'BooleanExpression' && showBoolean) {
            props.onChange(Object.assign(Object.assign({}, data), { Rule: {
                    BooleanExpression: '',
                } }));
        }
        else if (type === 'ObservableExpression' && showObservable) {
            props.onChange(Object.assign(Object.assign({}, data), { Rule: {
                    ObservableExpression: '',
                } }));
        }
        else if (type === 'AggregatedBooleanExpression' && showAggregation) {
            props.onChange(Object.assign(Object.assign({}, data), { Rule: {
                    AggregatedBooleanExpression: '',
                } }));
        }
        else {
            props.onChange(Object.assign(Object.assign({}, data), { Rule: {
                    Predicates: [
                        {
                            PredicateId: props.defaultPredicateId,
                        },
                    ],
                } }));
        }
    };
    const isValuesPredicateDef = (colDef) => colDef && ['Values', 'ExcludeValues'].includes(colDef.id);
    const filteredPredicateDefs = predicateDefs.filter((def) => {
        if (isValuesPredicateDef(def)) {
            return 'ColumnIds' in data.Scope && data.Scope.ColumnIds.length === 1;
        }
        return true;
    });
    const setBooleanExpression = (expression) => {
        props.onChange(Object.assign(Object.assign({}, data), { Rule: { BooleanExpression: expression } }));
    };
    const setReactiveExpression = (expression) => {
        props.onChange(Object.assign(Object.assign({}, data), { Rule: { ObservableExpression: expression } }));
    };
    const setAggregationExpression = (expression) => {
        props.onChange(Object.assign(Object.assign({}, data), { Rule: { AggregatedBooleanExpression: expression } }));
    };
    const initialData = (0, react_1.useMemo)(() => api.internalApi.getQueryPreviewData(), []);
    const baseClassName = 'ab-EntityRulesEditor';
    return (React.createElement(rebass_1.Flex, Object.assign({ className: baseClassName, flexDirection: "column", padding: 2, pt: 0, pl: 0 }, flexProps, { style: Object.assign({ height: '100%' }, flexProps === null || flexProps === void 0 ? void 0 : flexProps.style) }),
        children,
        React.createElement(Tabs_1.Tabs, { onValueChange: setType, value: selectedTab, pt: 2, pl: 2, style: { flex: 1, overflow: 'auto' } },
            showNoRule ? (React.createElement(Tabs_1.Tabs.Tab, { value: 'NoRule', style: { flex: 1 } },
                React.createElement(RuleTabTitle, { showRadio: showRadioButtons, checked: type === 'NoRule' }, "No Condition"))) : null,
            showNoRule ? (React.createElement(Tabs_1.Tabs.Content, { value: 'NoRule' },
                React.createElement(rebass_1.Text, { fontSize: 2, mb: 2 }, 'Format Column is always applied'))) : null,
            showPredicate ? (React.createElement(Tabs_1.Tabs.Tab, { value: 'Predicate', style: { flex: 1 } },
                React.createElement(RuleTabTitle, { showRadio: showRadioButtons, checked: type === 'Predicate' }, "Predicate"))) : null,
            showPredicate ? (React.createElement(Tabs_1.Tabs.Content, { "data-name": "Predicate", value: "Predicate" },
                React.createElement(EntityRulePredicatesEditor_1.EntityRulePredicatesEditor, { enablePredicateColumnId: props.enablePredicateColumnId, data: data, descriptions: descriptions, predicateDefs: filteredPredicateDefs, getPredicateDefsForColId: props.getPredicateDefsForColId, onChange: props.onChange }))) : null,
            showBoolean ? (React.createElement(QueryTab, { showRadio: showRadioButtons, value: "BooleanExpression", type: type, label: "Boolean" })) : null,
            showBoolean ? (React.createElement(Tabs_1.Tabs.Content, { "data-name": "BooleanExpression", value: 'BooleanExpression' }, (() => {
                var _a;
                const editor = (React.createElement(ExpressionEditor_1.ExpressionEditor, { type: 'boolean', module: module, value: (_a = data.Rule) === null || _a === void 0 ? void 0 : _a.BooleanExpression, onChange: setBooleanExpression, initialData: initialData, columns: api.columnApi.getQueryableColumns(), fields: api.expressionApi.internalApi.getAvailableFields(), namedQueries: api.namedQueryApi.getNamedQueries(), api: api, showQueryBuilder: props.showQueryBuilder }));
                return props.showQueryBuilder ? React.createElement(Panel_1.default, null, editor) : editor;
            })())) : null,
            showObservable ? (React.createElement(QueryTab, { showRadio: showRadioButtons, value: "ObservableExpression", type: type, label: "Observable" })) : null,
            showObservable ? (React.createElement(Tabs_1.Tabs.Content, { "data-name": "ObservableExpression", value: 'ObservableExpression' },
                React.createElement(ExpressionEditor_1.ExpressionEditor, { type: 'observable', module: module, value: (_a = data.Rule) === null || _a === void 0 ? void 0 : _a.ObservableExpression, onChange: setReactiveExpression, initialData: initialData, columns: api.columnApi.getQueryableColumns(), fields: api.expressionApi.internalApi.getAvailableFields(), namedQueries: api.namedQueryApi.getNamedQueries(), api: api }))) : null,
            showAggregation ? (React.createElement(QueryTab, { showRadio: showRadioButtons, value: "AggregatedBooleanExpression", type: type, label: "Aggregated Boolean" })) : null,
            showAggregation ? (React.createElement(Tabs_1.Tabs.Content, { "data-name": "AggregatedBooleanExpression", value: 'AggregatedBooleanExpression' },
                React.createElement(ExpressionEditor_1.ExpressionEditor, { type: 'aggregatedBoolean', module: module, value: (_b = data.Rule) === null || _b === void 0 ? void 0 : _b.AggregatedBooleanExpression, onChange: setAggregationExpression, initialData: initialData, columns: api.columnApi.getQueryableColumns(), fields: api.expressionApi.internalApi.getAvailableFields(), namedQueries: api.namedQueryApi.getNamedQueries(), api: api }))) : null)));
};
exports.EntityRulesEditor = EntityRulesEditor;
