/*!
 * Built by Revolist OU ❤️
 */
import sortedIndex from "lodash/sortedIndex";
/**
 * Pre-calculation
 * Dimension custom sizes for each cell
 * Keeps only changed sizes, skips origin size
 */
export function calculateDimensionData(originItemSize, newSizes = {}) {
    const positionIndexes = [];
    const positionIndexToItem = {};
    const indexToItem = {};
    // prepare order sorted new sizes and calculate changed real size
    const newIndexes = Object.keys(newSizes).map(Number).sort((a, b) => a - b);
    let previous;
    for (let i = 0; i < newIndexes.length; i++) {
        const itemIndex = newIndexes[i];
        const newItem = {
            itemIndex,
            start: 0,
            end: 0,
        };
        // if previous item was changed too
        if (previous) {
            const itemsBetween = (itemIndex - previous.itemIndex - 1) * originItemSize;
            newItem.start = itemsBetween + previous.end;
        }
        else {
            newItem.start = itemIndex * originItemSize;
        }
        newItem.end = newItem.start + newSizes[itemIndex];
        positionIndexes.push(newItem.start);
        indexToItem[itemIndex] = positionIndexToItem[i] = newItem;
        previous = newItem;
    }
    return {
        indexes: newIndexes,
        positionIndexes: [...positionIndexes],
        positionIndexToItem: Object.assign({}, positionIndexToItem),
        indexToItem,
    };
}
/**
 * Calculate item by position
 */
export const getItemByPosition = ({ indexes, positionIndexes, originItemSize, positionIndexToItem, }, pos) => {
    const item = {
        itemIndex: 0,
        start: 0,
        end: 0,
    };
    const currentPlace = indexes.length ? sortedIndex(positionIndexes, pos) : 0;
    // not found or first index
    if (!currentPlace) {
        item.itemIndex = Math.floor(pos / originItemSize);
        item.start = item.itemIndex * originItemSize;
        item.end = item.start + originItemSize;
        return item;
    }
    const positionItem = positionIndexToItem[currentPlace - 1];
    // if item has specified size
    if (positionItem.end > pos) {
        return positionItem;
    }
    // special size item was present before
    const relativePos = pos - positionItem.end;
    const relativeIndex = Math.floor(relativePos / originItemSize);
    item.itemIndex = positionItem.itemIndex + 1 + relativeIndex;
    item.start = positionItem.end + relativeIndex * originItemSize;
    item.end = item.start + originItemSize;
    return item;
};
export function getItemByIndex(dimension, index) {
    let item = {
        itemIndex: index,
        start: 0,
        end: 0,
    };
    // if item has specified size
    if (dimension.indexToItem[index]) {
        return dimension.indexToItem[index];
    }
    const currentPlace = dimension.indexes.length
        ? sortedIndex(dimension.indexes, index)
        : 0;
    // not found or first index
    if (!currentPlace) {
        item.start = item.itemIndex * dimension.originItemSize;
        item.end = item.start + dimension.originItemSize;
        return item;
    }
    // special size item was present before
    const positionItem = dimension.indexToItem[dimension.indexes[currentPlace - 1]];
    item.start =
        positionItem.end +
            (index - positionItem.itemIndex - 1) * dimension.originItemSize;
    item.end = item.start + dimension.originItemSize;
    return item;
}
