import { isFunctionLike } from '@angular-ru/cdk/function';
import { getValueByPath } from '@angular-ru/cdk/object';
import { isNotNil } from '@angular-ru/cdk/utils';
import { PrimaryKey } from '@angular-ru/cdk/typings';

function byPropertyValue(key, value) {
    return (arrayItem) => arrayItem[key] === value;
}

function exclude(valueOrValues) {
    const excludeValues = Array.isArray(valueOrValues) ? valueOrValues : [valueOrValues];
    return function (value) {
        return !excludeValues.includes(value);
    };
}

function hasManyItems(array) {
    return (array !== null && array !== void 0 ? array : []).length > 1;
}

function hasAtMostOneItem(array) {
    return !hasManyItems(array);
}

function hasNoItems(array) {
    return (array !== null && array !== void 0 ? array : []).length === 0;
}

function hasItems(array) {
    return !hasNoItems(array);
}

function hasOneItem(array) {
    return (array !== null && array !== void 0 ? array : []).length === 1;
}

function include(valueOrValues) {
    const includeValues = Array.isArray(valueOrValues) ? valueOrValues : [valueOrValues];
    return function (value) {
        return includeValues.includes(value);
    };
}

function partition(forArray, predicate) {
    return forArray.reduce((partitioning, element, ...rest) => {
        var _a;
        /**
         * Displays which array of a couple the value should fall into, depending on the predicate.
         * @type {number}
         */
        const fittingToPredicateCoupleIndex = predicate(element, ...rest) ? 0 : 1;
        (_a = partitioning[fittingToPredicateCoupleIndex]) === null || _a === void 0 ? void 0 : _a.push(element);
        return partitioning;
    }, [[], []]);
}

function pick(key) {
    return (value) => value[key];
}

function takeFirstItem(array) {
    return (Array.isArray(array) ? array[0] : undefined);
}

function takeLastItem(array) {
    return (Array.isArray(array) ? array[array.length - 1] : undefined);
}

function takeSecondItem(array) {
    return (Array.isArray(array) ? array[1] : undefined);
}

const thirdItemIndex = 2;
function takeThirdItem(array) {
    return (Array.isArray(array) ? array[thirdItemIndex] : undefined);
}

function unique(value, index, self) {
    return self.indexOf(value) === index;
}

function uniqueArrayOf(list, trackBy) {
    const uniqueMap = new Map();
    for (const item of list) {
        let trackKey;
        if (isFunctionLike(trackBy)) {
            trackKey = trackBy(item);
        }
        else {
            trackKey = getValueByPath(item, trackBy);
        }
        const isValidKey = isNotNil(trackKey) && !uniqueMap.has(trackKey);
        if (isValidKey) {
            uniqueMap.set(trackKey, item);
        }
    }
    return Array.from(uniqueMap).map(([, item]) => item);
}

// eslint-disable-next-line complexity,max-lines-per-function,sonarjs/cognitive-complexity
function updateArray(sourceArray, updatedArray, compareFnOrKey = PrimaryKey.ID) {
    var _a;
    const preparedSourceArray = sourceArray !== null && sourceArray !== void 0 ? sourceArray : [];
    const newSourceArray = [];
    const newUpdatedArray = (_a = updatedArray === null || updatedArray === void 0 ? void 0 : updatedArray.slice()) !== null && _a !== void 0 ? _a : [];
    const skipIndexes = new Set();
    // eslint-disable-next-line unicorn/no-for-loop
    for (let i = 0; i < preparedSourceArray.length; i++) {
        const currentItem = preparedSourceArray[i];
        let updated = false;
        // eslint-disable-next-line unicorn/no-for-loop
        for (let j = 0; j < newUpdatedArray.length; j++) {
            if (skipIndexes.has(j)) {
                continue;
            }
            let isCompared = false;
            const newItem = newUpdatedArray[j];
            if (isFunctionLike(compareFnOrKey)) {
                isCompared = compareFnOrKey(currentItem, newItem);
            }
            else {
                isCompared = (currentItem === null || currentItem === void 0 ? void 0 : currentItem[compareFnOrKey]) === (newItem === null || newItem === void 0 ? void 0 : newItem[compareFnOrKey]);
            }
            if (isCompared) {
                updated = true;
                newSourceArray.push(newItem);
                skipIndexes.add(j);
                break;
            }
        }
        if (!updated) {
            newSourceArray.push(currentItem);
        }
    }
    return newSourceArray;
}

/**
 * Generated bundle index. Do not edit.
 */

export { byPropertyValue, exclude, hasAtMostOneItem, hasItems, hasManyItems, hasNoItems, hasOneItem, include, partition, pick, takeFirstItem, takeLastItem, takeSecondItem, takeThirdItem, unique, uniqueArrayOf, updateArray };
//# sourceMappingURL=angular-ru-cdk-array.mjs.map
