import {environment} from '../environments/environment';

export function uuid_v4() {
    // @ts-ignore
    return ([1e7] + - 1e3 + - 4e3 + - 8e3 + - 1e11).replace(/[018]/g, c =>
        // tslint:disable-next-line:no-bitwise
        (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
    );
}

export function debounce(func: (...args: any[]) => any, timeout?: number) {
    let timer: number | undefined;
    return (...args: any[]) => {
        const next = () => func(...args);
        if (timer) {
            clearTimeout(timer);
        }
        timer = setTimeout(next, timeout > 0 ? timeout : 300);
    };
}

export function debugRun(closure: any) {
    if ( typeof closure === 'function' ) {
        return closure();
    }
}

export function isDebug() {
    return environment.outputDebug;
}

export function getCaller(error: Error) {
    const stackLines = error.stack.split(/\n|\sat\s/).map(x => x.trim()).filter(Boolean);
    const messageInStack = (new Error()).stack.split(/\n|\sat\s/).map(x => x.trim()).filter(Boolean)?.[0] === 'Error';
    return stackLines?.[messageInStack ? 2 : 1]?.split(/@|\s\(/)?.[0]?.replace(/[\/\\<]/g, '');
}

export function debug(...out: any[]) {
    const caller = getCaller(new Error());

    // Define different types of styles
    const baseStyles = [
        'color: #fff',
        'background-color: #449',
        'padding: 2px 4px',
        'border-radius: 2px'
    ].join(';');

    if ( environment.outputDebug ) {
        console.log(`%c${caller}`, baseStyles, ...out);
    }
}
