"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RowSummarySection = exports.RowSummarySectionSummary = exports.areSummaryRowsValid = void 0;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
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("../../../../AdaptableState/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 Flex_1 = require("../../../../components/Flex");
const areSummaryRowsValid = (layout) => {
    if (!layout.RowSummaries)
        return true;
    let valid = true;
    layout.RowSummaries?.find((rowSummary) => {
        for (const [_, fn] of Object.entries(rowSummary.ColumnsMap ?? {})) {
            if (!fn) {
                valid = 'Each row summary column requires 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) => {
        const expressionDef = availableScalarExpressions[expression];
        let firstArg = null;
        // filter out expressions without inputs defined
        if (!expressionDef?.inputs) {
            return null;
        }
        if (Array.isArray(expressionDef?.inputs?.[0])) {
            // @ts-ignore
            firstArg = expressionDef.inputs.find((input) => input.includes(columnInputType))?.[0];
        }
        else {
            firstArg = expressionDef.inputs[0];
        }
        if (columnInputType === firstArg) {
            return expression;
        }
        else {
            return null;
        }
    })
        .filter(Boolean);
    availableExpressionsForColumnTypeCache.set(key, expressions);
    return expressions;
};
const RowSummarySectionSummary = () => {
    const adaptable = (0, AdaptableContext_1.useAdaptable)();
    const { data: layout } = (0, OnePageAdaptableWizard_1.useOnePageAdaptableWizardContext)();
    return (React.createElement(Flex_1.Box, { className: "twa:flex twa:flex-col" }, layout.RowSummaries?.length ? (layout.RowSummaries.map((rowSummary, index) => {
        return (React.createElement(React.Fragment, null,
            React.createElement(Flex_1.Box, { className: "twa:mr-1 twa:mb-1", key: index },
                rowSummary.Position,
                ":",
                ' ',
                Object.keys(rowSummary.ColumnsMap).map((colId) => {
                    if (colId === 'Source' || colId === 'Uuid')
                        return null;
                    return (React.createElement(Tag_1.Tag, { className: "twa:mr-1", key: colId },
                        rowSummary.ColumnsMap[colId],
                        "(",
                        adaptable.api.columnApi.getFriendlyNameForColumnId(colId),
                        ")"));
                }))));
    })) : (React.createElement(Tag_1.Tag, null, "No Row Summaries"))));
};
exports.RowSummarySectionSummary = RowSummarySectionSummary;
const RowSummaryEditor = React.memo(({ rowSummary, onChange, availableScalarExpressions, onDelete, }) => {
    const { data: layout } = (0, OnePageAdaptableWizard_1.useOnePageAdaptableWizardContext)();
    const adaptable = (0, AdaptableContext_1.useAdaptable)();
    const columns = React.useMemo(() => {
        const colIds = adaptable.api.columnApi
            .getUIAvailableColumns()
            .filter((column) => {
            if (!['number', 'text', 'date'].includes(column.dataType))
                return false;
            return layout.TableColumns?.includes?.(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(Flex_1.Flex, { className: "twa:w-full" },
            React.createElement(Flex_1.Flex, { className: "twa:flex-1", alignItems: "center" }, "Row Summary"),
            React.createElement(Flex_1.Box, { className: "twa:mr-2" },
                React.createElement(SuspendToggleButton_1.SuspendToggleButton, { onSuspend: () => {
                        onChange({
                            ...rowSummary,
                            IsSuspended: true,
                        });
                    }, onUnSuspend: () => {
                        onChange({
                            ...rowSummary,
                            IsSuspended: false,
                        });
                    }, suspendableObject: rowSummary })),
            React.createElement(SimpleButton_1.default, { icon: "delete", onClick: () => {
                    onDelete();
                } })), className: "twa: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({
                            ...rowSummary,
                            Position: position,
                        });
                    } })),
            React.createElement(FormLayout_1.FormRow, { label: "" },
                React.createElement(CheckBox_1.CheckBox, { checked: rowSummary.IncludeOnlyFilteredRows ?? true, onChange: (IncludeOnlyFilteredRows) => {
                        onChange({
                            ...rowSummary,
                            IncludeOnlyFilteredRows,
                        });
                    } }, "Include Only Filtered Rows"))),
        React.createElement(Flex_1.Flex, { flexDirection: "column", className: "twa:mt-2 twa:mb-1" },
            React.createElement(Flex_1.Flex, { alignItems: "center", className: "twa:flex-1 twa:mb-2" }, "Column Aggregations"),
            React.createElement(Panel_1.default, { bodyProps: { className: 'twa:max-h-full ' }, className: "twa:h-[360px]" },
                React.createElement(ValueSelector_1.ValueSelector, { style: { maxHeight: '100%' }, showFilterInput: true, filter: Utilities_1.columnFilter, toIdentifier: (column) => column.columnId, toLabel: (option) => option.friendlyName ?? option.columnId, options: columns, toListLabel: (column) => {
                        const label = column.friendlyName ?? column.columnId;
                        if (!(column.columnId in (rowSummary.ColumnsMap ?? {}))) {
                            return label;
                        }
                        const expressionOptions = getAvailableExpressionsForColumnType(column.dataType, availableScalarExpressions).map((expression) => ({
                            label: expression,
                            value: expression,
                        }));
                        // check out if this layout has a aggregation with weighted column
                        const aggregation = layout.TableAggregationColumns?.find((agg) => agg.ColumnId === column.columnId)?.AggFunc;
                        if (aggregation &&
                            typeof aggregation === 'object' &&
                            aggregation.weightedColumnId) {
                            expressionOptions.push({
                                label: 'WEIGHTERD_AVG',
                                value: RowSummary_1.WEIGHTED_AVERAGE_AGGREGATED_FUNCTION,
                            });
                        }
                        const expression = rowSummary.ColumnsMap[column.columnId];
                        return (React.createElement(Flex_1.Flex, null,
                            React.createElement(Flex_1.Flex, { className: "twa:mr-2", alignItems: 'center' }, label),
                            React.createElement(Select_1.Select, { value: expression, options: expressionOptions, onChange: (expression) => {
                                    onChange({
                                        ...rowSummary,
                                        ColumnsMap: {
                                            ...rowSummary.ColumnsMap,
                                            [column.columnId]: expression,
                                        },
                                    });
                                } })));
                    }, value: Object.keys(rowSummary.ColumnsMap), onChange: (colIds) => {
                        const newColumnsMap = {};
                        colIds.forEach((colId) => {
                            newColumnsMap[colId] = rowSummary.ColumnsMap[colId] ?? null;
                        });
                        onChange({
                            ...rowSummary,
                            ColumnsMap: newColumnsMap,
                        });
                    } })))));
});
const RowSummarySection = (props) => {
    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(Flex_1.Flex, { className: "twa:mb-1" },
                    React.createElement(Flex_1.Flex, { className: "twa:flex-1" }),
                    React.createElement(SimpleButton_1.default, { onClick: () => {
                            props.onChange({
                                ...layout,
                                RowSummaries: [
                                    ...(layout.RowSummaries ?? []),
                                    {
                                        Position: 'Top',
                                        ColumnsMap: {},
                                        IncludeOnlyFilteredRows: true,
                                    },
                                ],
                            });
                        }, icon: "plus" }, "Add Row Summary")),
                (layout.RowSummaries ?? []).map((rowSummary, index) => {
                    return (React.createElement(RowSummaryEditor, { key: index, onDelete: () => {
                            const newSummaries = [...layout.RowSummaries];
                            newSummaries.splice(index, 1);
                            props.onChange({
                                ...layout,
                                RowSummaries: newSummaries,
                            });
                        }, availableScalarExpressions: availableScalarExpressions, rowSummary: rowSummary, onChange: (rowSummary) => {
                            const newSummaries = [...layout.RowSummaries];
                            newSummaries[index] = rowSummary;
                            props.onChange({
                                ...layout,
                                RowSummaries: newSummaries,
                            });
                        } }));
                })))));
};
exports.RowSummarySection = RowSummarySection;
