import { SortDirection, SortParams } from '../types/EventSorting';
import { ApplicationSettings as AppSettings } from '@nativescript/core';

import { UnitAll, UnitOutput } from '../entities/gen-event-new.types';
import { USER_TOKEN } from '~/constants/login-constants';
import { wsOrganizationUnit } from '~/constants/api.constants';
import { WebApiService } from '~/core/services/web-api.service';
import { UnitSearchModel } from '../types/UnitSearch';
import { Person } from '../types/common.types';
import { action, alert } from '@nativescript/core/ui/dialogs';
import { isIOS } from "nativescript-platform";
import { RadDataFormComponent } from 'nativescript-ui-dataform/angular';

export function formatPickerValues(vals: { DisplayName: any; ID: any; }[], defVal = "vše") {
    const items = vals.map(({ DisplayName, ID }) =>
        ({ key: ID.toString(), label: DisplayName }))
    if (!defVal) {
        return items;
    }
    return [
        { key: '', label: defVal },
        ...items
    ];
}

export function getPickerFormattedYearsAfter(start: number, count: number): Array<Picker> {
    return Array.from(Array(count).keys())
        .map(i => {
            const key = (start + i).toString()
            return {
                key, label: key
            }
        }).reverse();
}


export function pickPersonModal<Tval>(selector: (v: Tval) => string, arr: Tval[]) {
    if (arr.length === 0) {
        alert('Žádné osoby nebyly nalezeny')
        return
    }
    return action({
        title: 'Vyberte osobu',
        message: "Vyberte z nalezených osob",
        cancelButtonText: "Zrušit",
        actions: arr.map(v => selector(v))
    });
}

export function isEqual(obj1, obj2) {
    const props1 = Object.getOwnPropertyNames(obj1);
    const props2 = Object.getOwnPropertyNames(obj2);
    if (props1.length != props2.length) {
        return false;
    }
    for (let i = 0; i < props1.length; i++) {
        const prop = props1[i];
        const bothAreObjects = isObject(obj1[prop]) && isObject(obj2[prop])
        if ((!bothAreObjects && (obj1[prop] !== obj2[prop]))
            || (bothAreObjects && !isEqual(obj1[prop], obj2[prop]))) {
            return false;
        }
    }
    return true;
}
export function isObject(object) {
    return object != null && typeof object === 'object';
}

export function groupByPersonId(arr: Person[]) {
    return groupBy<number, Person>(p => p.id)(arr)
}

export function groupBy<Tkey, Tval>(fn: (v: Tval) => Tkey) {
    return (arr: Tval[]) => arr.reduce((acc, curr) => {
        const key = fn(curr)
        if (acc.has(key)) {
            acc.get(key).push(curr);
        } else {
            acc.set(key, [curr]);
        }
        return acc;
    }, new Map<Tkey, Tval[]>());

}

export function mergePersonMap(map: Map<number, Person[]>): Person[] {
    return Array.from(map.keys())
        .reduce((arr, id) => {
            const merged = map.get(id)
                .reduce((personRes, curr) =>
                ({
                    ...personRes,
                    roles: personRes.roles.concat(curr.roles),
                    extendedInfo: personRes.extendedInfo.concat(curr.extendedInfo),
                })
                )
            arr.push(merged)
            return arr;
        }, []);
}

export function isEqualJson(a, b) {
    return JSON.stringify(a) === JSON.stringify(b);
}

export interface Picker {
    key: string,
    label: string,
}

export const MAX_DATE = new Date(8640000000000000);
export function sortItems(items: any[], sortParams: SortParams, isDate = false) {
    const { sortByKey: key, sortDirection } = sortParams;
    const sortedItems = items.sort((a, b) => {
        let [prop_a, prop_b] = [a[key], b[key]]
        if (typeof prop_a === 'number' && typeof prop_b === 'number') {
            return prop_a - prop_b;
        } else if (isDate) {
            prop_a = prop_a ? new Date(prop_a) : MAX_DATE;
            prop_b = prop_b ? new Date(prop_b) : MAX_DATE;
            return prop_a.getTime() - prop_b.getTime();
        } else if (typeof prop_a === 'string' && typeof prop_b === 'string') {
            return prop_a.toString().toLowerCase()
                .localeCompare(prop_b.toString().toLowerCase());
        } else if (typeof prop_a === "boolean" && typeof prop_b === "boolean") {
            return prop_a.toString().localeCompare(prop_b.toString());
        }
    });
    return sortDirection === SortDirection.ASC.toString()
        ? sortedItems : sortedItems.reverse()
}


export async function loadUnits(webApiService: WebApiService, options: UnitSearchModel) {
    const tk = AppSettings.getString(USER_TOKEN)
    const input = new UnitAll(tk);
    input[options.criteria] = options.text;
    return webApiService.call(input,
        () => new UnitOutput(),
        wsOrganizationUnit
    ).toPromise();
}

export const DATE_FORMAT = 'dd.MM.yyyy';

export function setInputDateFormat(form: RadDataFormComponent | any, inputs: string[]) {
    inputs.forEach(name => {
        const input = form.dataForm.getPropertyByName(name)
        if (isIOS) {
            const dateFormatter = NSDateFormatter.alloc().init();
            dateFormatter.dateFormat = DATE_FORMAT;
            input.editor.ios.dateFormatter = dateFormatter;
        } else {
            const simpleDateFormat = new java.text.SimpleDateFormat(DATE_FORMAT, java.util.Locale.GERMAN);
            if (input.editor.setDateFormat) {
                input.editor.setDateFormat(simpleDateFormat);
            } else {
                input.editor.android.setDateFormat(simpleDateFormat);
            }
        }
    })
}