"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PivotAggregationsSection = exports.PivotAggregationsSectionSummary = exports.isPivotAggregationsSectionValid = 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 DropdownButton_1 = tslib_1.__importDefault(require("../../../../components/DropdownButton"));
const FormLayout_1 = tslib_1.__importStar(require("../../../../components/FormLayout"));
const Tabs_1 = require("../../../../components/Tabs");
const Tag_1 = require("../../../../components/Tag");
const AggregationColumns_1 = require("../../../../AdaptableState/Common/AggregationColumns");
const AdaptableContext_1 = require("../../../AdaptableContext");
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 StringExtensions_1 = tslib_1.__importDefault(require("../../../../Utilities/Extensions/StringExtensions"));
const Select_1 = require("../../../../components/Select");
const PivotColumnRow = (props) => {
    const adaptable = (0, AdaptableContext_1.useAdaptable)();
    const aggValue = (props.layout.PivotAggregationColumns || []).find((x) => x.ColumnId === props.column.columnId)?.AggFunc;
    const adaptableAggFunctions = [];
    if (props.column.dataType === 'number') {
        adaptableAggFunctions.push(AggregationColumns_1.WEIGHTED_AVERAGE_AGG_FN_NAME);
    }
    const aggOptions = [...props.column.availableAggregationFunctions, ...adaptableAggFunctions].map((fnName) => {
        return {
            label: fnName,
            onClick: () => {
                let aggCols = props.layout.PivotAggregationColumns || [];
                if (!aggCols) {
                    return;
                }
                const AggFuncValue = fnName === AggregationColumns_1.WEIGHTED_AVERAGE_AGG_FN_NAME
                    ? {
                        type: 'weightedAverage',
                        weightedColumnId: null,
                    }
                    : fnName;
                let found = false;
                aggCols = aggCols.map(({ ColumnId, AggFunc }) => {
                    if (ColumnId === props.column.columnId) {
                        found = true;
                        return {
                            ColumnId,
                            AggFunc: AggFuncValue,
                        };
                    }
                    return { ColumnId, AggFunc };
                });
                if (!found) {
                    aggCols.push({
                        ColumnId: props.column.columnId,
                        AggFunc: AggFuncValue,
                    });
                }
                props.onChangeAggFunction(aggCols);
            },
        };
    });
    const numericColumnsOptions = props.numberColumns
        .filter((col) => col.columnId !== props.column.columnId)
        .map((col) => {
        return {
            label: col.friendlyName,
            onClick: () => {
                let aggCols = props.layout.PivotAggregationColumns;
                if (!aggCols) {
                    return;
                }
                const AggFuncValue = {
                    type: 'weightedAverage',
                    weightedColumnId: col.columnId,
                };
                let found = false;
                aggCols = aggCols.map(({ ColumnId, AggFunc }) => {
                    if (ColumnId === props.column.columnId) {
                        found = true;
                        return {
                            ColumnId,
                            AggFunc: AggFuncValue,
                        };
                    }
                    return { ColumnId, AggFunc };
                });
                if (!found) {
                    aggCols.push({
                        ColumnId: props.column.columnId,
                        AggFunc: AggFuncValue,
                    });
                }
                props.onChangeAggFunction(aggCols);
            },
        };
    });
    const currentAggFnName = props.aggregationColumnsMap[props.column.columnId];
    let weightName = null;
    if (typeof aggValue === 'object' && aggValue.type === 'weightedAverage') {
        weightName = aggValue.weightedColumnId
            ? adaptable.api.columnApi.getFriendlyNameForColumnId(aggValue.weightedColumnId)
            : 'Select Weight';
    }
    const totalOptions = ['Off', 'Before', 'After', 'Pivot Specific'].map((totalVariant) => {
        return {
            label: totalVariant,
            onClick: () => {
                let aggCols = props.layout.PivotAggregationColumns;
                if (!aggCols) {
                    return;
                }
                aggCols = aggCols.map((aggCol) => {
                    if (aggCol.ColumnId === props.column.columnId) {
                        let updatedTotalColumn = false;
                        if (totalVariant === 'Before') {
                            updatedTotalColumn = 'before';
                        }
                        if (totalVariant === 'After') {
                            updatedTotalColumn = 'after';
                        }
                        if (totalVariant === 'Pivot Specific') {
                            updatedTotalColumn = props.layout.PivotColumns.map((pivotColId) => {
                                return {
                                    PivotColumnId: pivotColId,
                                    ShowTotal: true,
                                };
                            });
                        }
                        return {
                            ...aggCol,
                            Total: updatedTotalColumn,
                        };
                    }
                    return aggCol;
                });
                props.onChangeAggFunction(aggCols);
            },
        };
    });
    const currentAggCol = props.layout.PivotAggregationColumns?.find((aggCol) => aggCol.ColumnId === props.column.columnId);
    const currentTotal = currentAggCol?.Total
        ? currentAggCol.Total === true || currentAggCol.Total === 'before'
            ? 'Before'
            : currentAggCol.Total === 'after'
                ? 'After'
                : Array.isArray(currentAggCol.Total)
                    ? 'Pivot Specific'
                    : 'Off'
        : 'Off';
    const hasPivotSpecificTotals = Array.isArray(currentAggCol?.Total);
    const pivotSpecificTotals = Array.isArray(currentAggCol?.Total)
        ? currentAggCol.Total
        : props.layout.PivotColumns?.map((pivotColId) => ({
            PivotColumnId: pivotColId,
            ShowTotal: false,
        }));
    const handleTotalChange = (pivotColId, value) => {
        const updatedAggCols = (props.layout.PivotAggregationColumns || []).map((aggCol) => {
            if (aggCol.ColumnId === props.column.columnId) {
                const updatedTotals = pivotSpecificTotals.map((total) => {
                    if (total.PivotColumnId === pivotColId) {
                        return { ...total, ShowTotal: value };
                    }
                    return total;
                });
                return { ...aggCol, Total: updatedTotals };
            }
            return aggCol;
        });
        props.onChangeAggFunction(updatedAggCols);
    };
    const pivotTotalOptions = ['Off', 'Before', 'After'].map((option) => ({
        label: option,
        value: option === 'Off' ? false : option.toLowerCase(),
    }));
    return (React.createElement(rebass_1.Box, { "data-name": props.column.columnId, className: "ab-Layout-Wizard__ColumnRow" },
        React.createElement(rebass_1.Flex, { alignItems: "flex-start" },
            React.createElement(rebass_1.Flex, { flex: "0 0 auto", alignItems: "center" },
                React.createElement(rebass_1.Flex, { minWidth: 80 }, props.column.friendlyName),
                aggValue && (React.createElement(DropdownButton_1.default, { columns: ['label'], items: aggOptions, ml: 2 }, currentAggFnName)),
                currentAggFnName === AggregationColumns_1.WEIGHTED_AVERAGE_AGG_FN_NAME && (React.createElement(rebass_1.Flex, { backgroundColor: "primary", ml: 3, alignItems: "center" },
                    React.createElement(rebass_1.Text, null, "Weight"),
                    ' ',
                    React.createElement(DropdownButton_1.default, { columns: ['label'], items: numericColumnsOptions, ml: 2 }, weightName))),
                aggValue && (React.createElement(rebass_1.Flex, { backgroundColor: "primary", ml: 3, alignItems: "center" },
                    React.createElement(rebass_1.Text, null, "Total"),
                    ' ',
                    React.createElement(DropdownButton_1.default, { columns: ['label'], items: totalOptions, ml: 2 }, currentTotal)))),
            hasPivotSpecificTotals && (React.createElement(rebass_1.Flex, { ml: 2, pl: 2, flexWrap: "wrap", flex: "1 1 auto", alignItems: "center", style: {
                    minWidth: '200px',
                    borderLeft: '1px solid var(--ab-color-text-on-primary)',
                    rowGap: '8px',
                    columnGap: '12px',
                } }, props.layout.PivotColumns.map((pivotColId) => {
                const pivotTotalSetting = pivotSpecificTotals.find((t) => t.PivotColumnId === pivotColId);
                const currentValue = pivotTotalSetting == undefined
                    ? 'Off'
                    : pivotTotalSetting.ShowTotal === false
                        ? 'Off'
                        : pivotTotalSetting.ShowTotal === 'before' ||
                            pivotTotalSetting.ShowTotal === true ||
                            pivotTotalSetting.ShowTotal == undefined
                            ? 'Before'
                            : pivotTotalSetting.ShowTotal === 'after'
                                ? 'After'
                                : 'Off';
                return (React.createElement(rebass_1.Flex, { key: pivotColId, alignItems: "center" },
                    React.createElement(rebass_1.Text, { mr: 1 },
                        adaptable.api.columnApi.getFriendlyNameForColumnId(pivotColId),
                        ":"),
                    React.createElement(DropdownButton_1.default, { columns: ['label'], items: pivotTotalOptions.map((opt) => ({
                            label: opt.label,
                            onClick: () => handleTotalChange(pivotColId, opt.value),
                        })) }, currentValue)));
            }))))));
};
const isPivotAggregationsSectionValid = (data) => {
    const weightedAvg = data.PivotAggregationColumns
        ? (data.PivotAggregationColumns || [])
            .map((agg) => agg.AggFunc)
            .find((agg) => typeof agg === 'object' && agg.type === 'weightedAverage')
        : null;
    if (weightedAvg && !weightedAvg.weightedColumnId) {
        return 'The Weighted Average Aggregation requires a Weighted Column';
    }
    return true;
};
exports.isPivotAggregationsSectionValid = isPivotAggregationsSectionValid;
const PivotAggregationsSectionSummary = () => {
    const adaptable = (0, AdaptableContext_1.useAdaptable)();
    const { data: layout } = (0, OnePageAdaptableWizard_1.useOnePageAdaptableWizardContext)();
    const pivotAggregationColumns = layout.PivotAggregationColumns || [];
    let content = null;
    if (pivotAggregationColumns.length) {
        content = (React.createElement(FormLayout_1.default, null, pivotAggregationColumns.map(({ ColumnId: colId, AggFunc: aggFunc }) => (React.createElement(FormLayout_1.FormRow, { key: colId, label: adaptable.api.columnApi.getFriendlyNameForColumnId(colId) },
            React.createElement(Tag_1.Tag, null, typeof aggFunc === 'object' ? aggFunc.type : aggFunc))))));
    }
    else {
        content = React.createElement(Tag_1.Tag, null, "No Pivot Column Aggregations");
    }
    return React.createElement(rebass_1.Box, null, content);
};
exports.PivotAggregationsSectionSummary = PivotAggregationsSectionSummary;
const PivotAggregationsSection = (props) => {
    const adaptable = (0, AdaptableContext_1.useAdaptable)();
    const { data: layout } = (0, OnePageAdaptableWizard_1.useOnePageAdaptableWizardContext)();
    const allAggregableColumns = adaptable.api.columnApi.getAggregatableColumns();
    const allColumns = adaptable.api.columnApi.getUIAvailableColumns();
    const numberColumns = adaptable.api.columnApi.getNumericColumns();
    const sortedAggregableColumns = React.useMemo(() => {
        return ArrayExtensions_1.default.sortArrayWithOrder(allAggregableColumns.map((col) => col.columnId), (layout.PivotAggregationColumns ?? []).map((col) => col.ColumnId), { sortUnorderedItems: false }).map((colId) => adaptable.api.columnApi.getColumnWithColumnId(colId));
    }, [layout, allAggregableColumns]);
    const handleColumnsSelectionChange = React.useCallback((columnIds) => {
        const currentAggColumns = layout.PivotAggregationColumns ?? [];
        const PivotAggregationColumns = columnIds.map((colId) => {
            return {
                ColumnId: colId,
                AggFunc: currentAggColumns.find((x) => x.ColumnId === colId)?.AggFunc ??
                    adaptable.api.columnApi.getDefaultAggFunc(colId),
                TotalColumn: currentAggColumns.find((x) => x.ColumnId === colId)?.Total,
            };
        });
        props.onChange({
            ...layout,
            PivotAggregationColumns,
        });
    }, [layout]);
    const handleAggregationChange = React.useCallback((pivotAggregationColumns) => {
        if (pivotAggregationColumns.some((aggCol) => aggCol.Total !== false || aggCol.Total !== null)) {
            // if any Aggregation Column has a Total Column, we need to disable the Pivot Group Total Column
            delete layout['PivotColumnTotal'];
        }
        props.onChange({
            ...layout,
            PivotAggregationColumns: pivotAggregationColumns,
        });
    }, [layout]);
    const aggregationColumnsMap = React.useMemo(() => {
        const allColumnsMap = allColumns.reduce((acc, col) => {
            acc[col.columnId] = col;
            return acc;
        }, {});
        return (layout.PivotAggregationColumns || []).reduce((acc, { ColumnId: colId, AggFunc: aggFunc }) => {
            let fn = aggFunc;
            let fnName = '';
            if (typeof fn === 'boolean') {
                fnName = allColumnsMap[colId].aggregationFunction;
            }
            if (typeof fn === 'object' && fn.type === 'weightedAverage') {
                fnName = AggregationColumns_1.WEIGHTED_AVERAGE_AGG_FN_NAME;
            }
            else if (typeof fn === 'string') {
                fnName = fn;
            }
            acc[colId] = fnName;
            return acc;
        }, {});
    }, [layout]);
    const handleSuppressAggFuncInHeader = (checked) => {
        props.onChange({
            ...layout,
            SuppressAggFuncInHeader: checked,
        });
    };
    const checkIfPivotColumnTotalEnabled = () => {
        // check that all AggregationColumns have identical AggFuncs
        const aggregationColumns = layout.PivotAggregationColumns;
        if (!aggregationColumns || aggregationColumns.length === 0) {
            return true;
        }
        const firstAggFuncName = (0, AggregationColumns_1.getAggFuncName)(aggregationColumns[0].AggFunc);
        if (layout.PivotAggregationColumns?.some((aggCol) => (0, AggregationColumns_1.getAggFuncName)(aggCol.AggFunc) !== firstAggFuncName)) {
            return 'Requires identical aggregation on all columns';
        }
        // check that no Aggregation Total Column is enabled
        const hasAggregationTotalColumn = aggregationColumns.some((aggCol) => aggCol.Total !== false && aggCol.Total != null);
        if (hasAggregationTotalColumn) {
            return 'Can only be enabled when no Aggregation Total Column is present';
        }
        return true;
    };
    const isPivotColumnTotalEnabled = checkIfPivotColumnTotalEnabled();
    return (React.createElement(Tabs_1.Tabs, { style: { height: '100%' } },
        React.createElement(Tabs_1.Tabs.Tab, null, "Column Aggregations"),
        React.createElement(Tabs_1.Tabs.Content, null,
            React.createElement(rebass_1.Flex, null,
                React.createElement(FormLayout_1.default, null,
                    React.createElement(FormLayout_1.FormRow, { label: 'Omit Aggregation from Header' },
                        React.createElement(CheckBox_1.CheckBox, { checked: layout.SuppressAggFuncInHeader, onChange: handleSuppressAggFuncInHeader })),
                    React.createElement(FormLayout_1.FormRow, { label: 'Grand Total Row' },
                        React.createElement(Select_1.Select, { style: { width: 120 }, options: ['top', 'bottom'].map((position) => {
                                return {
                                    label: StringExtensions_1.default.CapitaliseFirstLetter(position),
                                    value: position,
                                };
                            }), placeholder: "Off", value: layout.GrandTotalRow, onChange: (value) => {
                                props.onChange({
                                    ...layout,
                                    GrandTotalRow: value,
                                });
                            }, isClearable: true })),
                    React.createElement(FormLayout_1.FormRow, { label: 'Pivot Grand Total' },
                        React.createElement(Select_1.Select, { style: { width: 120 }, options: ['before', 'after'].map((position) => {
                                return {
                                    label: StringExtensions_1.default.CapitaliseFirstLetter(position),
                                    value: position,
                                };
                            }), placeholder: "Off", value: layout.PivotGrandTotal, onChange: (value) => {
                                props.onChange({
                                    ...layout,
                                    PivotGrandTotal: value,
                                });
                            }, isClearable: true })),
                    React.createElement(FormLayout_1.FormRow, { label: 'Pivot Column Total' }, isPivotColumnTotalEnabled === true ? (React.createElement(Select_1.Select, { style: { width: 120 }, options: ['before', 'after'].map((position) => {
                            return {
                                label: StringExtensions_1.default.CapitaliseFirstLetter(position),
                                value: position,
                            };
                        }), placeholder: "Off", value: layout.PivotColumnTotal, onChange: (value) => {
                            props.onChange({
                                ...layout,
                                PivotColumnTotal: value,
                            });
                        }, isClearable: true })) : (React.createElement(rebass_1.Text, { marginLeft: 1, style: { fontStyle: 'italic' } }, isPivotColumnTotalEnabled))))),
            React.createElement(ValueSelector_1.ValueSelector, { showFilterInput: true, showSelectedOnlyPosition: "top", filter: Utilities_1.columnFilter, toIdentifier: (option) => `${option.columnId}`, toLabel: (option) => option.friendlyName ?? option.columnId, toListLabel: (column) => (React.createElement(PivotColumnRow, { onChangeAggFunction: handleAggregationChange, layout: layout, column: column, aggregationColumnsMap: aggregationColumnsMap, numberColumns: numberColumns })), options: sortedAggregableColumns, value: (layout.PivotAggregationColumns || []).map((col) => col.ColumnId), allowReorder: true, xSelectedLabel: () => {
                    return `Active aggregations:`;
                }, onChange: handleColumnsSelectionChange }))));
};
exports.PivotAggregationsSection = PivotAggregationsSection;
