function [reduced_cGenAll] = deduplicate_cGen(cGenAll)
%% 
% ---------- SETTINGS ----------
SHARED_MIN = 3;   % "more than 2 names" => 3 or more
overlapThreshold = 0.6; % adjustable threshold (60%)

% ---------- PREP: make names unique within each cell ----------
nCells = numel(cGenAll);
cellNames = cell(nCells,1);
for i = 1:nCells
    if isfield(cGenAll{i}, 'names') && ~isempty(cGenAll{i}.names)
        cGenAll{i}.names = unique(cGenAll{i}.names(:)'); % row, unique
        cellNames{i} = cGenAll{i}.names;
    else
        cellNames{i} = {};
    end
end

% ---------- PAIRWISE SHARED NAME COUNTS ----------
sharedCounts = zeros(nCells);
for i = 1:nCells-1
    ni = cellNames{i};
    for j = i+1:nCells
        nj = cellNames{j};
        sharedCounts(i,j) = numel(intersect(ni, nj));
        sharedCounts(j,i) = sharedCounts(i,j);
    end
end

% ---------- REPORT: pairs that share >= SHARED_MIN ----------
fprintf('\nPairs sharing >= %d names:\n', SHARED_MIN);
anyPair = false;
for i = 1:nCells-1
    for j = i+1:nCells
        if sharedCounts(i,j) >= SHARED_MIN
            fprintf('  Cells [%d, %d] share %d names\n', i, j, sharedCounts(i,j));
            anyPair = true;
        end
    end
end
if ~anyPair
    fprintf('  (none)\n');
end

% ---------- REPORT: groups (2+ cells) within connected components ----------
% Build graph: edge if a pair shares >= SHARED_MIN names
A = sharedCounts >= SHARED_MIN;
A = A - diag(diag(A));        % zero diagonal
G = graph(A);
[compIdx, ~] = conncomp(G);   % component index per node

fprintf('\nGroups (components) with 2+ cells and their ALL-INTERSECTION count:\n');
hasGroup = false;
groupOverlaps = cell(1, max(compIdx)); % store per-component percentages

for c = 1:max(compIdx)
    members = find(compIdx == c);
    if numel(members) >= 2
        % names shared by ALL cells in this component
        commonNames = cellNames{members(1)};
        for k = 2:numel(members)
            commonNames = intersect(commonNames, cellNames{members(k)});
        end

        % calculate percentage overlaps per cell
        sharedCount = numel(commonNames);
        percents = zeros(1,numel(members));
        for k = 1:numel(members)
            if isempty(cellNames{members(k)})
                percents(k) = 0;
            else
                percents(k) = sharedCount / numel(cellNames{members(k)});
            end
        end
        groupOverlaps{c} = percents;

        % print report with percentages
        pctStr = sprintf('%.0f%% ', percents*100);
        fprintf('  Cells %s share %d names in common (across ALL) → [%s]\n', ...
            mat2str(members), sharedCount, strtrim(pctStr));

        % special note if all exceed threshold
        if all(percents >= overlapThreshold)
            fprintf('    - All members ≥ %.0f%%, only the smallest index will be kept.\n', ...
                overlapThreshold*100);
        end

        hasGroup = true;
    end
end
if ~hasGroup
    fprintf('  (none)\n');
end

% ---------- REDUCTION: drop cells with >= overlapThreshold ----------
keepMask = true(1, nCells);
for c = 1:max(compIdx)
    members = find(compIdx == c);
if numel(members) >= 2
    percents = groupOverlaps{c};
    if isempty(percents), continue; end

    dropIdx = percents >= overlapThreshold;
    drop = members(dropIdx);
    keep = members(~dropIdx);

    % If everyone is above threshold, keep just one
    if isempty(keep)
        % Keep the one with the smallest percentage
        [minPercent, minIdx] = min(percents(dropIdx));

        % If multiple have the same smallest percentage, pick the smallest index
        ties = find(percents(dropIdx) == minPercent);
        if numel(ties) > 1
            [~, smallestIdx] = min(drop(ties));
            keep = drop(ties(smallestIdx));
        else
            keep = drop(minIdx);
        end

        % Drop everything else
        drop = setdiff(members, keep);
    end

    % Apply to mask
    keepMask(drop) = false;
    if isempty(drop)
        fprintf('Component %d: Dropping no cells\n', c);
    else
        fprintf('Component %d: Dropping cells %s (>= %.0f%% overlap), keeping %s\n', ...
            c, mat2str(drop), overlapThreshold*100, mat2str(keep));
    end
end

end

reduced_cGenAll = cGenAll(keepMask);
fprintf('\nReduced set has %d of %d cells.\n', numel(reduced_cGenAll), nCells);
end