import { InnerRowIndex } from "../../dataReshape/index.js";
import { executeDynamicFilter, isDynamicFilter } from "../../dataSelector/selector.js";
const dynamicFilterConfig = {
    table: [
        'bodyCellStyle'
    ],
    pivotTable: [
        'bodyCellStyle'
    ],
    bar: [
        'barStyle',
        'annotationPoint',
        'annotationVerticalLine',
        'label'
    ],
    barParallel: [
        'barStyle',
        'annotationPoint',
        'annotationVerticalLine',
        'label'
    ],
    barPercent: [
        'barStyle',
        'annotationPoint',
        'annotationVerticalLine',
        'label'
    ],
    column: [
        'barStyle',
        'annotationPoint',
        'annotationHorizontalLine',
        'label'
    ],
    columnParallel: [
        'barStyle',
        'annotationPoint',
        'annotationHorizontalLine',
        'label'
    ],
    columnPercent: [
        'barStyle',
        'annotationPoint',
        'annotationHorizontalLine',
        'label'
    ],
    line: [
        'lineStyle',
        'pointStyle',
        'annotationPoint',
        'annotationHorizontalLine',
        'label'
    ],
    area: [
        'lineStyle',
        'pointStyle',
        'annotationPoint',
        'annotationHorizontalLine',
        'label'
    ],
    areaPercent: [
        'lineStyle',
        'pointStyle',
        'annotationPoint',
        'annotationHorizontalLine',
        'label'
    ],
    dualAxis: [
        'barStyle',
        'lineStyle',
        'pointStyle',
        'annotationPoint',
        'annotationHorizontalLine',
        'label'
    ],
    scatter: [
        'pointStyle',
        'annotationPoint',
        'annotationHorizontalLine',
        'annotationVerticalLine',
        'label'
    ],
    histogram: [
        'annotationHorizontalLine'
    ],
    boxPlot: [
        'annotationHorizontalLine'
    ]
};
const generateDynamicFilterKeyPaths = ()=>{
    const result = {};
    for (const [chartType, baseKeyPaths] of Object.entries(dynamicFilterConfig))result[chartType] = baseKeyPaths.flatMap((basePath)=>[
            `${basePath}[].dynamicFilter`,
            `${basePath}.dynamicFilter`
        ]);
    return result;
};
const dynamicFilterKeyPathsByChartType = generateDynamicFilterKeyPaths();
const getBasePathsForDeepClone = (chartType)=>dynamicFilterConfig[chartType] ?? [];
const parseKeyPath = (path)=>path.split('.').map((segment)=>{
        if (segment.endsWith('[]')) return {
            key: segment.slice(0, -2),
            isArray: true
        };
        return {
            key: segment,
            isArray: false
        };
    });
const getValuesByKeyPath = (target, path)=>{
    const segments = parseKeyPath(path);
    let current = [
        target
    ];
    for (const segment of segments){
        const next = [];
        for (const node of current){
            if (!node || 'object' != typeof node) continue;
            const value = node[segment.key];
            if (segment.isArray) {
                if (Array.isArray(value)) next.push(...value);
            } else if (void 0 !== value) next.push(value);
        }
        current = next;
    }
    return current;
};
const collectDynamicFiltersByKeyPaths = (target, chartType)=>{
    const paths = dynamicFilterKeyPathsByChartType[chartType] ?? [];
    if (!paths.length) return [];
    return paths.flatMap((path)=>getValuesByKeyPath(target, path)).filter((value)=>isDynamicFilter(value) && !!value?.code);
};
const executeDynamicFiltersAndInject = async (filters, dataset)=>{
    if (!filters.length || !dataset.length) return;
    await Promise.all(filters.map(async (filter)=>{
        const { success, data, error } = await executeDynamicFilter(filter, dataset);
        filter.result = {
            success,
            error,
            data: data
        };
    }));
};
const deepCloneDynamicFilterPaths = (vseed, chartType)=>{
    const basePaths = getBasePathsForDeepClone(chartType);
    if (!basePaths.length) return {
        ...vseed
    };
    const clonedVseed = {
        ...vseed
    };
    for (const basePath of basePaths){
        if (!(basePath in clonedVseed)) continue;
        const value = clonedVseed[basePath];
        if (Array.isArray(value)) clonedVseed[basePath] = value.map((item)=>{
            if (!item || 'object' != typeof item) return item;
            const clonedItem = {
                ...item
            };
            if (clonedItem.dynamicFilter && 'object' == typeof clonedItem.dynamicFilter) clonedItem.dynamicFilter = {
                ...clonedItem.dynamicFilter
            };
            return clonedItem;
        });
        else if (value && 'object' == typeof value) {
            clonedVseed[basePath] = {
                ...value
            };
            if (clonedVseed[basePath].dynamicFilter && 'object' == typeof clonedVseed[basePath].dynamicFilter) clonedVseed[basePath].dynamicFilter = {
                ...clonedVseed[basePath].dynamicFilter
            };
        }
    }
    return clonedVseed;
};
const prepare = async (builder)=>{
    if (builder.isPrepared || !builder.vseed || !builder.vseed?.chartType || !builder.vseed.dataset) return;
    const filters = collectDynamicFiltersByKeyPaths(builder.vseed, builder.vseed.chartType);
    if (!filters.length) {
        builder.isPrepared = true;
        return;
    }
    const clonedVseed = deepCloneDynamicFilterPaths(builder.vseed, builder.vseed.chartType);
    const originalDataset = clonedVseed.dataset;
    let datasetWithIndex = originalDataset;
    if (!originalDataset[0] || !(InnerRowIndex in originalDataset[0])) datasetWithIndex = originalDataset.map((item, index)=>({
            ...item,
            [InnerRowIndex]: index
        }));
    builder.vseed = {
        ...clonedVseed,
        dataset: datasetWithIndex
    };
    const clonedFilters = collectDynamicFiltersByKeyPaths(builder.vseed, builder.vseed.chartType);
    try {
        await executeDynamicFiltersAndInject(clonedFilters, datasetWithIndex);
    } catch (e) {
        throw new Error(`Failed to execute dynamic filters: ${e.message}`);
    }
    builder.isPrepared = true;
};
export { prepare };

//# sourceMappingURL=prepare.js.map