import { findAllMeasures } from "../../../../utils/index.js";
const datasetHierarchy = (spec, context)=>{
    const result = {
        ...spec
    };
    const { advancedVSeed } = context;
    const { datasetReshapeInfo, dataset, measures } = advancedVSeed;
    const { foldInfo, unfoldInfo } = datasetReshapeInfo[0];
    const hierarchyFields = advancedVSeed.encoding?.hierarchy || [];
    const measureKeys = findAllMeasures(measures).map((m)=>m.id);
    if (!hierarchyFields.length) {
        result.data = [
            {
                id: 'data',
                values: dataset
            }
        ];
        return result;
    }
    const tree = buildTree(dataset, hierarchyFields, foldInfo, unfoldInfo, measureKeys);
    result.data = [
        {
            id: 'data',
            values: tree
        }
    ];
    return result;
};
const buildTree = (dataset, hierarchyFields, foldInfo, unfoldInfo, measureKeys = [])=>{
    const { measureValue, measureId, measureName } = foldInfo;
    const { encodingColor, encodingColorId } = unfoldInfo;
    const collectFields = [
        measureId,
        measureName,
        encodingColor,
        encodingColorId
    ].filter(Boolean);
    const root = {
        name: 'root',
        children: []
    };
    dataset.forEach((datum)=>{
        let currentNode = root;
        for(let i = 0; i < hierarchyFields.length; i++){
            const field = hierarchyFields[i];
            const value = String(datum[field]);
            let child = currentNode.children.find((c)=>c.name === value);
            if (!child) {
                child = {
                    name: value,
                    children: []
                };
                for(let j = 0; j <= i; j++)child[hierarchyFields[j]] = datum[hierarchyFields[j]];
                currentNode.children.push(child);
            }
            currentNode = child;
        }
        if (!currentNode.isLeaf) {
            Object.assign(currentNode, datum);
            currentNode.isLeaf = true;
            if (measureValue) currentNode[measureValue] = 0;
            measureKeys.forEach((key)=>{
                currentNode[key] = 0;
            });
            collectFields.forEach((field)=>{
                currentNode[`_set_${field}`] = new Set();
            });
        }
        if (measureValue && void 0 !== datum[measureValue]) currentNode[measureValue] += Number(datum[measureValue]);
        measureKeys.forEach((key)=>{
            if (void 0 !== datum[key]) currentNode[key] = (currentNode[key] || 0) + Number(datum[key]);
        });
        collectFields.forEach((field)=>{
            if (datum[field]) currentNode[`_set_${field}`].add(datum[field]);
        });
        if (measureValue) currentNode.value = currentNode[measureValue];
    });
    const flattenSets = (node)=>{
        collectFields.forEach((field)=>{
            const setKey = `_set_${field}`;
            if (node[setKey]) {
                node[field] = Array.from(node[setKey]).join('+');
                delete node[setKey];
            }
        });
    };
    const mergeCollectFieldsFromChildren = (node)=>{
        collectFields.forEach((field)=>{
            const merged = new Set();
            node.children.forEach((child)=>{
                if (child[field]) child[field].split('+').forEach((v)=>merged.add(v));
            });
            if (merged.size > 0) node[field] = Array.from(merged).join('+');
        });
    };
    const aggregate = (node)=>{
        if (node.isLeaf) {
            flattenSets(node);
            return node.value || 0;
        }
        if (!node.children?.length) return node.value || 0;
        let sum = 0;
        node.children.forEach((child)=>{
            sum += aggregate(child);
            measureKeys.forEach((key)=>{
                node[key] = (node[key] || 0) + (child[key] || 0);
            });
        });
        node.value = sum;
        if (measureValue) node[measureValue] = sum;
        mergeCollectFieldsFromChildren(node);
        return sum;
    };
    root.children.forEach(aggregate);
    return root.children;
};
export { buildTree, datasetHierarchy };

//# sourceMappingURL=datasetHierarchy.js.map