
export namespace Ex {
    export const dateToDisplay = (d: Date): string => {
        let month = `${d.getMonth() + 1}`
        if ( month.length < 2 ) month = `0${month}`
        let date = `${d.getDate()}`
        if ( date.length < 2 ) date = `0${date}`
        return `${d.getFullYear()}-${month}-${date}`
    }

    export const dateToInput = (d: Date): string => {
        let month = `${d.getMonth() + 1}`
        if ( month.length < 2 ) month = `0${month}`
        let date = `${d.getDate()}`
        if ( date.length < 2 ) date = `0${date}`
        let hours = `${d.getHours()}`
        if ( hours.length < 2 ) hours = `0${date}`
        let minutes = `${d.getMinutes()}`
        if ( minutes.length < 2 ) minutes = `0${date}`

        return `${d.getFullYear()}-${month}-${date}T${hours}:${minutes}`
    }

    export const uuid = (): string => {
        // @ts-ignore
        return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
            (c ^ crypto.getRandomValues(new Uint8Array(1))[0]! & 15 >> c / 4).toString(16)
        )
    }

    export const debounce  = <TArgs extends [], TReturn>(handler: (...args: TArgs) => TReturn, delayMs: number = 500): ((...args: TArgs) => Promise<TReturn>) => {
        let timeout: any = null

        return (...args: TArgs): Promise<TReturn> => {
            clearTimeout(timeout)

            return new Promise<TReturn>((res, rej) => {
                timeout = setTimeout(() => {
                    try {
                        res(handler(...args))
                    } catch (e) {
                        rej(e)
                    }
                }, delayMs)
            })
        }
    }

    export class Subject<T> {

    }
}
