// Bin distribution (pareto) and clustered-by-group bin bars — generalized
// from tsmap's own charts/aggregate.ts. Pure math, no DOM.
import { isYieldEligibleDie } from '../core/dies.js';
/**
 * One bar per bin, across all `items`, sorted by count descending. Excludes
 * partial/edge-excluded dies via `isYieldEligibleDie` — the same population
 * the adjacent Yield panel uses — so the two panels' totals reconcile for
 * the same wafer/group. Items carrying precomputed `hardBinCounts`/
 * `softBinCounts` (see `BinItem`) contribute those directly, skipping the
 * per-die walk for that item.
 */
export function buildBinParetoData(items, binType) {
    const counts = new Map();
    let totalDies = 0;
    for (const item of items) {
        const precomputed = binType === 'hbin' ? item.hardBinCounts : item.softBinCounts;
        if (precomputed) {
            for (const [binStr, count] of Object.entries(precomputed)) {
                const bin = Number(binStr);
                totalDies += count;
                counts.set(bin, (counts.get(bin) ?? 0) + count);
            }
            continue;
        }
        for (const die of item.dies ?? []) {
            if (!isYieldEligibleDie(die))
                continue;
            const bin = binType === 'hbin' ? die.hbin : die.sbin;
            if (bin === undefined)
                continue;
            totalDies++;
            counts.set(bin, (counts.get(bin) ?? 0) + 1);
        }
    }
    const data = Array.from(counts.entries()).map(([bin, count]) => ({
        label: `Bin ${bin}`,
        value: count,
        percent: totalDies > 0 ? (count / totalDies) * 100 : 0,
        itemCount: 1,
        binCode: bin,
    }));
    data.sort((a, b) => b.value - a.value);
    return data;
}
/**
 * Clustered bin pareto: every group's bin counts side by side, so groups
 * compare directly bin-by-bin. Unlike the plain pareto, this is never a
 * restrict-to-one-group view — all groups are always shown at once,
 * matching tsmap's actual behavior (a wholly different panel swapped in for
 * bin pareto when grouping is active, not a variant of it).
 */
export function buildBinClusterData(groups, binType) {
    const groupOrder = groups.map(g => g.key);
    const bins = new Map();
    const binOrder = [];
    function addCount(bin, gi, n) {
        let b = bins.get(bin);
        if (!b) {
            b = { total: 0, counts: [] };
            bins.set(bin, b);
            binOrder.push(bin);
        }
        b.total += n;
        b.counts[gi] = (b.counts[gi] ?? 0) + n;
    }
    groups.forEach((g, gi) => {
        for (const item of g.items) {
            const precomputed = binType === 'hbin' ? item.hardBinCounts : item.softBinCounts;
            if (precomputed) {
                for (const [binStr, count] of Object.entries(precomputed))
                    addCount(Number(binStr), gi, count);
                continue;
            }
            for (const die of item.dies ?? []) {
                if (!isYieldEligibleDie(die))
                    continue;
                const bin = binType === 'hbin' ? die.hbin : die.sbin;
                if (bin === undefined)
                    continue;
                addCount(bin, gi, 1);
            }
        }
    });
    const sortedBins = binOrder.slice().sort((a, b) => bins.get(b).total - bins.get(a).total);
    const clusterBins = sortedBins.map(bin => {
        const b = bins.get(bin);
        return {
            binCode: bin,
            label: `Bin ${bin}`,
            total: b.total,
            counts: groupOrder.map((_, gi) => b.counts[gi] ?? 0),
        };
    });
    return { groups: groupOrder, bins: clusterBins };
}
//# sourceMappingURL=binPareto.js.map