var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
import { AXIS_TICK_LABEL_SIZE, MAX_CHARACTERS, MIN_CHARACTERS, SET_LABEL_SIZE } from './constants';
export var findIntersections = function (data) {
    var setsCombinations = {};
    var individualSets = {};
    data.forEach(function (_a) {
        var name = _a.name, sets = _a.sets;
        sets.forEach(function (set) {
            if (!individualSets[set]) {
                individualSets[set] = [];
            }
            individualSets[set].push(name);
        });
        var generateCombinations = function (subset, index) {
            if (index === sets.length) {
                if (subset.length > 0) {
                    var key = subset.sort().join(',');
                    if (!setsCombinations[key]) {
                        setsCombinations[key] = [];
                    }
                    setsCombinations[key].push(name);
                }
                return;
            }
            generateCombinations(subset, index + 1);
            generateCombinations(__spreadArray(__spreadArray([], subset, true), [sets[index]], false), index + 1);
        };
        generateCombinations([], 0);
    });
    var intersections = Object.entries(setsCombinations)
        .map(function (_a, index) {
        var key = _a[0], elements = _a[1];
        return ({
            index: index,
            sets: key.split(','),
            size: elements.length,
            elements: elements
        });
    })
        .sort(function (a, b) { return b.size - a.size; });
    var sets = Object.entries(individualSets).map(function (_a, index) {
        var name = _a[0], elements = _a[1];
        return ({
            index: index,
            name: name,
            size: elements.length,
            elements: elements
        });
    });
    return { intersections: intersections, sets: sets };
};
export var getMatrixData = function (xScale, yScale, intersections, sets) {
    var circles = intersections.flatMap(function (intersection, i) {
        return sets.map(function (set) { return ({
            cx: xScale(String(i)) + xScale.bandwidth() / 2,
            cy: yScale(set.name) + yScale.bandwidth() / 2,
            isPresent: intersection.sets.includes(set.name),
            intersectionIndex: intersection.index
        }); });
    });
    var lines = intersections.reduce(function (acc, intersection, i) {
        var activeSetIndices = intersection.sets
            .map(function (name) { return sets.findIndex(function (set) { return set.name === name; }); })
            .filter(function (i) { return i >= 0; })
            .sort(function (a, b) { return a - b; });
        if (activeSetIndices.length > 1) {
            var firstIdx = activeSetIndices[0];
            var lastIdx = activeSetIndices[activeSetIndices.length - 1];
            var x = xScale(String(i)) + xScale.bandwidth() / 2;
            var y1 = yScale(sets[firstIdx].name) + yScale.bandwidth() / 2;
            var y2 = yScale(sets[lastIdx].name) + yScale.bandwidth() / 2;
            return __spreadArray(__spreadArray([], acc, true), [{ x: x, y1: y1, y2: y2, intersectionIndex: intersection.index }], false);
        }
        return acc;
    }, []);
    return { circles: circles, lines: lines };
};
export var truncateLabels = function (sets, maxLabelsWidth) {
    var newTruncatedLabels = [];
    var maxWidth = 0;
    var tempSvgElement = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
    document.body.appendChild(tempSvgElement);
    var tempTextElement = document.createElementNS('http://www.w3.org/2000/svg', 'text');
    tempTextElement.setAttribute('font-size', SET_LABEL_SIZE);
    tempSvgElement.appendChild(tempTextElement);
    sets.forEach(function (_a) {
        var name = _a.name;
        var truncatedText = name.length > MAX_CHARACTERS ? name.slice(0, MAX_CHARACTERS) + '...' : name;
        tempTextElement.textContent = truncatedText;
        while (tempTextElement.getBBox().width > maxLabelsWidth && truncatedText.length > MIN_CHARACTERS) {
            truncatedText = truncatedText.slice(0, -4) + '...';
            tempTextElement.textContent = truncatedText;
        }
        newTruncatedLabels.push(truncatedText);
        maxWidth = Math.max(maxWidth, tempTextElement.getBBox().width);
    });
    document.body.removeChild(tempSvgElement);
    return { labels: newTruncatedLabels, maxWidth: maxWidth };
};
export var calculateTicksWidth = function (ticks) {
    var tempSvgElement = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
    var tempTextElement = document.createElementNS('http://www.w3.org/2000/svg', 'text');
    tempTextElement.setAttribute('font-size', AXIS_TICK_LABEL_SIZE);
    tempSvgElement.appendChild(tempTextElement);
    document.body.appendChild(tempSvgElement);
    var maxWidth = ticks.reduce(function (maxWidth, tick) {
        tempTextElement.textContent = String(tick);
        return Math.max(maxWidth, tempTextElement.getBBox().width);
    }, 0);
    document.body.removeChild(tempSvgElement);
    return maxWidth;
};
