import {min, max, range} from 'lodash';

export function tansformBackendData(histogramData) {
    let [time, step, items] = histogramData;
    return {
        time,
        step,
        min: min(items.map(([left, right, count]) => left)),
        max: max(items.map(([left, right, count]) => right)),
        items: items.map(([left, right, count]) => ({left, right, count}))
    };
}

export function computeNewHistogram(histogram, min, max, binsNum = 30) {
    if (max === min) {
        // Create bins even if all the data has a single value.
        max = min * 1.1 + 1;
        min = min / 1.1 - 1;
    }
    let stepWidth = (max - min) / binsNum;
    let itemIndex = 0;
    return range(min, max, stepWidth).map(binLeft => {
        let binRight = binLeft + stepWidth;
        let yValue = 0;
        while (itemIndex < histogram.items.length) {
            let itemRight = Math.min(max, histogram.items[itemIndex].right);
            let itemLeft = Math.max(min, histogram.items[itemIndex].left);
            let overlap = Math.min(itemRight, binRight) - Math.max(itemLeft, binLeft);
            let count = (overlap / (itemRight - itemLeft)) * histogram.items[itemIndex].count;
            yValue += overlap > 0 ? count : 0;
            // If `itemRight` is bigger than `binRight`, then this bin is
            // finished and there also has data for the next bin, so don't increment
            // `itemIndex`.
            if (itemRight > binRight) {
                break;
            }
            itemIndex++;
        }
        return {x: binLeft, dx: stepWidth, y: yValue};
    });
}

export function tansformToVisData(tempData, time, step) {
    return tempData.map(function (dataItem) {
        return [time, step, dataItem.x + dataItem.dx / 2, Math.floor(dataItem.y)];
    });
}

export function originDataToChartData(originData) {
    let tempData = originData.map(tansformBackendData);
    let globalMin = min(tempData.map(({min}) => min));
    let globalMax = max(tempData.map(({max}) => max));
    let chartData = tempData.map(function (item) {
        let histoBins = computeNewHistogram(item, globalMin, globalMax);
        let {time, step} = item;
        return {
            time,
            step,
            items: tansformToVisData(histoBins, time, step)
        };
    });
    return {
        min: globalMin,
        max: globalMax,
        chartData
    };
}
