"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.computeLegendSelector = void 0;
const get_partition_specs_1 = require("./get_partition_specs");
const tree_1 = require("./tree");
const color_library_wrappers_1 = require("../../../../common/color_library_wrappers");
const colors_1 = require("../../../../common/colors");
const legend_1 = require("../../../../common/legend");
const create_selector_1 = require("../../../../state/create_selector");
const get_legend_config_selector_1 = require("../../../../state/selectors/get_legend_config_selector");
const get_settings_spec_1 = require("../../../../state/selectors/get_settings_spec");
const common_1 = require("../../../../utils/common");
const legend_2 = require("../../../../utils/legend");
const config_types_1 = require("../../layout/types/config_types");
const group_by_rollup_1 = require("../../layout/utils/group_by_rollup");
const viewmodel_1 = require("../../layout/viewmodel/viewmodel");
function compareLegendItemNames(aItem, bItem, locale) {
    return aItem.item.label.localeCompare(bItem.item.label, locale);
}
function compareDescendingLegendItemValues(aItem, bItem) {
    return (aItem.item.depth ?? -1) - (bItem.item.depth ?? -1) || bItem.node[group_by_rollup_1.AGGREGATE_KEY] - aItem.node[group_by_rollup_1.AGGREGATE_KEY];
}
exports.computeLegendSelector = (0, create_selector_1.createCustomCachedSelector)([get_settings_spec_1.getSettingsSpecSelector, get_partition_specs_1.getPartitionSpecs, get_legend_config_selector_1.getLegendConfigSelector, tree_1.getTrees], (settings, [spec], { flatLegend, legendMaxDepth, legendPosition }, trees) => {
    if (!spec)
        return [];
    const sortingFn = flatLegend && settings.legendSort;
    const { locale } = settings;
    return trees.flatMap((tree) => {
        const customSortingFn = sortingFn
            ? (aItem, bItem) => sortingFn({
                smAccessorValue: tree.smAccessorValue,
                specId: aItem.item.seriesIdentifiers[0]?.specId,
                key: aItem.item.seriesIdentifiers[0]?.key,
            }, {
                smAccessorValue: tree.smAccessorValue,
                specId: bItem.item.seriesIdentifiers[0]?.specId,
                key: bItem.item.seriesIdentifiers[0]?.key,
            })
            : undefined;
        const useHierarchicalLegend = (0, legend_2.isHierarchicalLegend)(flatLegend, legendPosition);
        const { valueFormatter } = spec;
        const items = walkTree(spec.id, useHierarchicalLegend, valueFormatter, tree.tree, spec.layers, 0);
        return items
            .filter((d) => {
            const depth = d.item.depth ?? -1;
            if (d.item.childId === group_by_rollup_1.HIERARCHY_ROOT_KEY) {
                return false;
            }
            return depth < legendMaxDepth;
        })
            .sort(customSortingFn ??
            (spec.layout === config_types_1.PartitionLayout.waffle
                ? compareDescendingLegendItemValues
                : (0, viewmodel_1.isLinear)(spec.layout)
                    ? (a, b) => compareLegendItemNames(a, b, locale)
                    : () => 0))
            .map(({ item }) => item);
    });
});
function walkTree(specId, useHierarchicalLegend, valueFormatter, tree, layers, depth, uniqueNames = new Set(), legendItems = []) {
    if (tree.length === 0) {
        return legendItems;
    }
    for (const [key, node] of tree) {
        const layer = layers[depth - 1];
        const formatter = layer?.nodeLabel ?? ((d) => `${d}`);
        const fill = layer?.shape?.fillColor ?? (0, color_library_wrappers_1.RGBATupleToString)(colors_1.Colors.DarkOpaqueRed.rgba);
        const fillColor = typeof fill === 'function' ? fill(key, node.sortIndex, node, tree) : fill;
        const label = formatter(key);
        const joinedPath = node[group_by_rollup_1.PATH_KEY].map((d) => d.value).join('##');
        const uniqueKey = `${depth}--${joinedPath}--${label}--${fillColor}--${node[group_by_rollup_1.AGGREGATE_KEY]}`;
        if (!(0, common_1.isNil)(key) && !uniqueNames.has(uniqueKey)) {
            legendItems.push({
                item: {
                    color: fillColor,
                    childId: key,
                    label,
                    path: node[group_by_rollup_1.PATH_KEY],
                    depth: node[group_by_rollup_1.DEPTH_KEY] - 1,
                    seriesIdentifiers: [{ key, specId }],
                    keys: [],
                    values: [
                        {
                            value: node[group_by_rollup_1.AGGREGATE_KEY],
                            label: valueFormatter(node[group_by_rollup_1.AGGREGATE_KEY]),
                            type: legend_1.LegendValue.Value,
                        },
                    ],
                },
                node,
            });
            uniqueNames.add(uniqueKey);
        }
        const children = node[group_by_rollup_1.CHILDREN_KEY];
        walkTree(specId, useHierarchicalLegend, valueFormatter, children, layers, depth + 1, uniqueNames, legendItems);
    }
    return legendItems;
}
//# sourceMappingURL=compute_legend.js.map