import * as cloneDeep from "lodash.clonedeep";
import { FormGroup } from "@angular/forms";

export class LinqHelper {

    static groupBy = (list, keyGetter) => {
        const map = new Map();
        list.forEach((item) => {
            const key = keyGetter(item);
            const collection = map.get(key);
            if (!collection) {
                map.set(key, [item]);
            } else {
                collection.push(item);
            }
        });
        return map;
    }

    static sort = (records: Array<any>, key: string) => {
        records.sort((a: any, b: any) => {
            return a[key] < b[key]
                ? -1
                : a[key] > b[key]
                    ? 1
                    : 0;
        });
    }

    static cloneDeepArray = <T>(data: Array<T>): Array<T> => {
        const newData = data.map(x => ({ ...x }));
        return newData as Array<T>;
    }

    static cloneDeep = <T>(data: T): T => {
        return cloneDeep(data) as T;
    }

    static uniqueOnlyBy = (value, index, self) => {
        return index === self.findIndex((t) => (
            t.name === value.name
        ));
    }

    static uniqueOnlyByAlt = (value, index, self, name) => {
        return index === self.findIndex((t) => (
            t[name] === value[name]
        ));
    }

    static uniqueOnly = (value, index, self) => {
        return self.indexOf(value) === index;
    }

    static compare = (a, b, key: string) => {
        if (a[key] < b[key]) {
            return -1;
        }
        if (a[key] > b[key]) {
            return 1;
        }
        return 0;
    }

    static toNormalCase = (text: string): string => {
        const result = text.replace(/([A-Z])/g, " $1");
        const finalResult = result.charAt(0).toUpperCase() + result.slice(1);
        return finalResult;
    }

    static stuffIn = (originalText: string, stuffInText: string) => {
        return originalText.indexOf(stuffInText) !== -1
            ? originalText.replace(new RegExp(`(${stuffInText})`, 'gi'), ` ${stuffInText} `).replace(/\s+/g, " ")
            : originalText.trim() + " " + stuffInText;
    }

    static trimFormValues = (form: FormGroup) => {

        const setValue = (control: any) => {
            control.setValue(control.value.toString().trim().split(" ").filter(x => !!x).join(" "));
        }

        const patchHelper = (controls: any) => {
            const keys = Object.keys(controls);
            keys.forEach(key => {
                const subControls = controls[key]["controls"];
                !subControls && typeof controls[key].value === "string" && setValue(controls[key]);
                subControls && patchHelper(subControls);
            })
        }

        patchHelper(form["controls"]);
    }

}