import pullAllWith from 'lodash/pullAllWith';
import unionWith from 'lodash/unionWith';
import get from 'lodash/get';

export class Util {
    static thrs = {};
    static injectNg(injectables, injectArr, scope){
        for (let i = 0, len = injectables.length; i < len; i++){
            scope[injectArr[i]] = injectables[i];
        }
    }
    static setTranslation(string){
        if (angular.isDefined(string)) {
            if (angular.isString(string)) {
                return {
                    translationId: string
                }
            } else if (angular.isObject(string)) {
                return string;
            }
        }
    }
    static setTranslations(obj){
        if (angular.isObject(obj)){
            for (let key in obj){
                obj[key] = this.setTranslation(obj[key])
            }
        }
        return obj;
    }
    static removeFromArray(arr, key, value) {
        if (!arr || !arr.length) return;
        let { length } = arr;
        while(length--){
            if (arr[length][key] === value) arr.splice(length, 1);
        }
    }
    static isEmpty(arr){
        return !arr || !arr.length;
    }
    static generateId() {
        let S4 = function() {
           return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
        };
        return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
    }
    static pushWith(original, predicate, toPush, compare){
        let compared = pullAllWith(toPush, compare, predicate);
        return unionWith(original, compared, predicate);
    }
    static throttle(lastCall, ms = 150){
        if (this.thrs[lastCall]) {
            let now = new Date().getTime();
            if (now - this.thrs[lastCall] < ms) {
                return false;
            }
            this.thrs[lastCall] = now;
            return true;
        } else {
            this.thrs[lastCall] = new Date().getTime();
            return true;
        }
    }
    static isObjectEmpty(object) { 
        for (let i in object) return false;
        return true;
    }
    static exists(obj, path, ...predicates){
        if (!obj || this.isObjectEmpty(obj)) return false;
        let operator = 'and';
        if (path.includes(':') && path.substr(path.indexOf(':')+1) === 'or'){
            operator = 'or';
        }
        let value = get(obj, path);
        if (!value) return false;
        if (predicates) {
            return operator === 'and' ? !predicates.some(predicate => !predicate(value)) : predicates.some(predicate => !predicate(value));
        } else {
            return !!value;
        }
    }
    static deleteIfExists(obj, property){
        let newObj = angular.copy(obj);
        if (property in newObj) delete newObj[property];
        return newObj;
    }
}