"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RowSummarySection = exports.RowGroupingSectionSummary = exports.areSummaryRowsValid = void 0;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const rebass_1 = require("rebass");
const CheckBox_1 = require("../../../../components/CheckBox");
const FormLayout_1 = tslib_1.__importStar(require("../../../../components/FormLayout"));
const Panel_1 = tslib_1.__importDefault(require("../../../../components/Panel"));
const Select_1 = require("../../../../components/Select");
const SimpleButton_1 = tslib_1.__importDefault(require("../../../../components/SimpleButton"));
const Tabs_1 = require("../../../../components/Tabs");
const Tag_1 = require("../../../../components/Tag");
const RowSummary_1 = require("../../../../PredefinedConfig/Common/RowSummary");
const adaptableQlUtils_1 = require("../../../../Utilities/adaptableQlUtils");
const ModuleConstants_1 = require("../../../../Utilities/Constants/ModuleConstants");
const aggregatedScalarExpressionFunctions_1 = require("../../../../Utilities/ExpressionFunctions/aggregatedScalarExpressionFunctions");
const AdaptableContext_1 = require("../../../AdaptableContext");
const SuspendToggleButton_1 = require("../../../Components/Buttons/SuspendToggleButton");
const ValueSelector_1 = require("../../../Components/ValueSelector");
const OnePageAdaptableWizard_1 = require("../../../Wizard/OnePageAdaptableWizard");
const Utilities_1 = require("./Utilities");
const ArrayExtensions_1 = tslib_1.__importDefault(require("../../../../Utilities/Extensions/ArrayExtensions"));
const areSummaryRowsValid = (layout) => {
    var _a;
    if (!layout.RowSummaries)
        return true;
    let valid = true;
    (_a = layout.RowSummaries) === null || _a === void 0 ? void 0 : _a.find((rowSummary) => {
        var _a;
        for (const [_, fn] of Object.entries((_a = rowSummary.ColumnsMap) !== null && _a !== void 0 ? _a : {})) {
            if (!fn) {
                valid = 'All row summary columns must have an aggregation function.';
                return true;
            }
        }
    });
    return valid;
};
exports.areSummaryRowsValid = areSummaryRowsValid;
const availableExpressionsForColumnTypeCache = new Map();
const getAvailableExpressionsForColumnType = (columnType, availableScalarExpressions) => {
    const key = columnType;
    if (availableExpressionsForColumnTypeCache.has(key)) {
        return availableExpressionsForColumnTypeCache.get(key);
    }
    const columnInputType = (0, adaptableQlUtils_1.mapColumnDataTypeToExpressionFunctionType)(columnType);
    const expressions = Object.keys(availableScalarExpressions)
        .filter((availableExpression) => {
        if (!aggregatedScalarExpressionFunctions_1.aggregatedExpressionFunctions.includes(availableExpression)) {
            // is custom
            return true;
        }
        return Boolean(RowSummary_1.summarySupportedExpressions.includes(availableExpression));
    })
        .map((expression) => {
        var _a, _b;
        const expressionDef = availableScalarExpressions[expression];
        let firstArg = null;
        // filter out expressions without inputs defined
        if (!(expressionDef === null || expressionDef === void 0 ? void 0 : expressionDef.inputs)) {
            return null;
        }
        if (Array.isArray((_a = expressionDef === null || expressionDef === void 0 ? void 0 : expressionDef.inputs) === null || _a === void 0 ? void 0 : _a[0])) {
            // @ts-ignore
            firstArg = (_b = expressionDef.inputs.find((input) => input.includes(columnInputType))) === null || _b === void 0 ? void 0 : _b[0];
        }
        else {
            firstArg = expressionDef.inputs[0];
        }
        if (columnInputType === firstArg) {
            return expression;
        }
        else {
            return null;
        }
    })
        .filter(Boolean);
    availableExpressionsForColumnTypeCache.set(key, expressions);
    return expressions;
};
const RowGroupingSectionSummary = () => {
    var _a;
    const adaptable = (0, AdaptableContext_1.useAdaptable)();
    const { data: layout } = (0, OnePageAdaptableWizard_1.useOnePageAdaptableWizardContext)();
    return (React.createElement(rebass_1.Box, null, ((_a = layout.RowGroupedColumns) === null || _a === void 0 ? void 0 : _a.length) ? (layout.RowGroupedColumns.map((columnId) => (React.createElement(Tag_1.Tag, { mr: 1, key: columnId }, adaptable.api.columnApi.getFriendlyNameForColumnId(columnId))))) : (React.createElement(Tag_1.Tag, null, "No Row Grouping"))));
};
exports.RowGroupingSectionSummary = RowGroupingSectionSummary;
const RowSummaryEditor = React.memo(({ rowSummary, onChange, availableScalarExpressions, onDelete, }) => {
    var _a;
    const { data: layout } = (0, OnePageAdaptableWizard_1.useOnePageAdaptableWizardContext)();
    const adaptable = (0, AdaptableContext_1.useAdaptable)();
    const columns = React.useMemo(() => {
        const colIds = adaptable.api.columnApi
            .getColumns()
            .filter((column) => {
            var _a, _b;
            if (!['Number', 'String', 'Date'].includes(column.dataType))
                return false;
            return (_b = (_a = layout.Columns) === null || _a === void 0 ? void 0 : _a.includes) === null || _b === void 0 ? void 0 : _b.call(_a, column.columnId);
        })
            .map((c) => c.columnId);
        return ArrayExtensions_1.default.sortArrayWithOrder(colIds, Object.keys(rowSummary.ColumnsMap), {
            sortUnorderedItems: false,
        }).map((colId) => adaptable.api.columnApi.getColumnWithColumnId(colId));
    }, [rowSummary.ColumnsMap]);
    return (React.createElement(Panel_1.default, { header: React.createElement(rebass_1.Flex, { style: { width: '100%' } },
            React.createElement(rebass_1.Flex, { flex: 1, alignItems: "center" }, "Row Summary"),
            React.createElement(rebass_1.Box, { mr: 2 },
                React.createElement(SuspendToggleButton_1.SuspendToggleButton, { onSuspend: () => {
                        onChange(Object.assign(Object.assign({}, rowSummary), { IsSuspended: true }));
                    }, onUnSuspend: () => {
                        onChange(Object.assign(Object.assign({}, rowSummary), { IsSuspended: false }));
                    }, suspendableObject: rowSummary })),
            React.createElement(SimpleButton_1.default, { icon: "delete", onClick: () => {
                    onDelete();
                } })), p: 2 },
        React.createElement(FormLayout_1.default, null,
            React.createElement(FormLayout_1.FormRow, { label: "Position" },
                React.createElement(Select_1.Select, { options: [
                        {
                            label: 'Top',
                            value: 'Top',
                        },
                        {
                            label: 'Bottom',
                            value: 'Bottom',
                        },
                    ], value: rowSummary.Position, onChange: (position) => {
                        onChange(Object.assign(Object.assign({}, rowSummary), { Position: position }));
                    } })),
            React.createElement(FormLayout_1.FormRow, { label: "" },
                React.createElement(CheckBox_1.CheckBox, { checked: (_a = rowSummary.IncludeOnlyFilteredRows) !== null && _a !== void 0 ? _a : true, onChange: (IncludeOnlyFilteredRows) => {
                        onChange(Object.assign(Object.assign({}, rowSummary), { IncludeOnlyFilteredRows }));
                    } }, "Include Only Filtered Rows"))),
        React.createElement(rebass_1.Flex, { flexDirection: 'column', mt: 2, mb: 1 },
            React.createElement(rebass_1.Flex, { alignItems: "center", flex: 1, mb: 2 }, "Column Aggregations"),
            React.createElement(Panel_1.default, { bodyProps: { maxHeight: '100%' }, style: { height: 360 } },
                React.createElement(ValueSelector_1.ValueSelector, { style: { maxHeight: '100%' }, showFilterInput: true, filter: Utilities_1.columnFilter, toIdentifier: (column) => column.columnId, toLabel: (option) => { var _a; return (_a = option.friendlyName) !== null && _a !== void 0 ? _a : option.columnId; }, options: columns, xSelectedLabel: () => {
                        return 'Active Aggregations:';
                    }, toListLabel: (column) => {
                        var _a, _b, _c;
                        const label = (_a = column.friendlyName) !== null && _a !== void 0 ? _a : column.columnId;
                        if (!(column.columnId in ((_b = rowSummary.ColumnsMap) !== null && _b !== void 0 ? _b : {}))) {
                            return label;
                        }
                        const expressionOptions = getAvailableExpressionsForColumnType(column.dataType, availableScalarExpressions).map((expression) => ({
                            label: expression,
                            value: expression,
                        }));
                        // check out if this layout has a aggregation with wighted column
                        const aggregation = (_c = layout.AggregationColumns) === null || _c === void 0 ? void 0 : _c[column.columnId];
                        if (aggregation &&
                            typeof aggregation === 'object' &&
                            aggregation.weightedColumnId) {
                            expressionOptions.push({
                                label: 'WEIGHTERD_AVG',
                                value: RowSummary_1.WEIGHTED_AVERAGE_AGGREATED_FUNCTION,
                            });
                        }
                        const expression = rowSummary.ColumnsMap[column.columnId];
                        return (React.createElement(rebass_1.Flex, null,
                            React.createElement(rebass_1.Flex, { mr: 2, alignItems: 'center' }, label),
                            React.createElement(Select_1.Select, { value: expression, options: expressionOptions, onChange: (expression) => {
                                    onChange(Object.assign(Object.assign({}, rowSummary), { ColumnsMap: Object.assign(Object.assign({}, rowSummary.ColumnsMap), { [column.columnId]: expression }) }));
                                } })));
                    }, value: Object.keys(rowSummary.ColumnsMap), onChange: (colIds) => {
                        const newColumnsMap = {};
                        colIds.forEach((colId) => {
                            var _a;
                            newColumnsMap[colId] = (_a = rowSummary.ColumnsMap[colId]) !== null && _a !== void 0 ? _a : null;
                        });
                        onChange(Object.assign(Object.assign({}, rowSummary), { ColumnsMap: newColumnsMap }));
                    } })))));
});
const RowSummarySection = (props) => {
    var _a;
    const adaptable = (0, AdaptableContext_1.useAdaptable)();
    const { data: layout } = (0, OnePageAdaptableWizard_1.useOnePageAdaptableWizardContext)();
    const availableScalarExpressions = React.useMemo(() => {
        const sytemExpressions = adaptable.api.internalApi
            .getQueryLanguageService()
            .getModuleExpressionFunctionsMap(ModuleConstants_1.LayoutModuleId).aggregatedScalarFunctions;
        return sytemExpressions;
    }, []);
    return (React.createElement(Tabs_1.Tabs, { style: { height: '100%' } },
        React.createElement(Tabs_1.Tabs.Tab, null, "Row Summaries"),
        React.createElement(Tabs_1.Tabs.Content, null,
            React.createElement("div", null,
                React.createElement(rebass_1.Flex, { mb: 1 },
                    React.createElement(rebass_1.Flex, { flex: 1 }),
                    React.createElement(SimpleButton_1.default, { onClick: () => {
                            var _a;
                            props.onChange(Object.assign(Object.assign({}, layout), { RowSummaries: [
                                    ...((_a = layout.RowSummaries) !== null && _a !== void 0 ? _a : []),
                                    {
                                        Position: 'Top',
                                        ColumnsMap: {},
                                        IncludeOnlyFilteredRows: true,
                                    },
                                ] }));
                        }, icon: "plus" }, "Add Row Summary")),
                ((_a = layout.RowSummaries) !== null && _a !== void 0 ? _a : []).map((rowSummary, index) => {
                    return (React.createElement(RowSummaryEditor, { key: index, onDelete: () => {
                            const newSummaries = [...layout.RowSummaries];
                            newSummaries.splice(index, 1);
                            props.onChange(Object.assign(Object.assign({}, layout), { RowSummaries: newSummaries }));
                        }, availableScalarExpressions: availableScalarExpressions, rowSummary: rowSummary, onChange: (rowSummary) => {
                            const newSummaries = [...layout.RowSummaries];
                            newSummaries[index] = rowSummary;
                            props.onChange(Object.assign(Object.assign({}, layout), { RowSummaries: newSummaries }));
                        } }));
                })))));
};
exports.RowSummarySection = RowSummarySection;
