import * as i0 from '@angular/core';
import { InjectionToken, Injector, InjectFlags, Injectable, Inject, NgModule } from '@angular/core';
import { isNil, isNotNil, checkValueIsFilled } from '@angular-ru/cdk/utils';
import * as i1 from '@angular/material/core';
import { DatePipe } from '@angular/common';
import { toNumber } from '@angular-ru/cdk/number';
import { isString } from '@angular-ru/cdk/string';

const MAX_YEAR = 3000;
function dateStringToDate(date) {
    if (date instanceof Date) {
        return date;
    }
    const firstItem = 1;
    const parsedDate = (date || '')
        .replace(/^(\d)/, '0$1')
        .replace(/\.(\d)\./, '.0$1.')
        .replace('..', '.01.')
        .replace(/^\./, '01.')
        .replace(/(\d{3})\./g, (str) => str.slice(firstItem))
        .replace(/(\d{2}).(\d{2}).(\d{4})/, '$2/$1/$3')
        .replace(/00\//g, '01/');
    const dateValue = new Date(parsedDate);
    if (dateValue.getFullYear() > MAX_YEAR) {
        return new Date();
    }
    return isNaN(dateValue.getTime()) ? new Date() : dateValue;
}

const SUGGESTION_STRATEGY_MAP = new InjectionToken('Suggestion strategy map');

class DateSuggestionComposer {
    constructor(suggestionStrategyMap, injector) {
        this.suggestionStrategyMap = suggestionStrategyMap;
        this.injector = injector;
    }
    getSuggestions() {
        return Object.keys(this.suggestionStrategyMap);
    }
    getStrategy(type) {
        var _a;
        const descriptor = this.suggestionStrategyMap[type];
        const strategy = Injector.create({
            providers: [
                { provide: descriptor.strategy, useClass: descriptor.strategy },
                ...((_a = descriptor.providers) !== null && _a !== void 0 ? _a : [])
            ],
            parent: this.injector
        }).get(descriptor.strategy, null, InjectFlags.Optional);
        if (isNil(strategy)) {
            throw new Error('This type of date suggestion is not supported');
        }
        return strategy;
    }
}
/** @nocollapse */ DateSuggestionComposer.ɵfac = function DateSuggestionComposer_Factory(t) { return new (t || DateSuggestionComposer)(i0.ɵɵinject(SUGGESTION_STRATEGY_MAP), i0.ɵɵinject(i0.Injector)); };
/** @nocollapse */ DateSuggestionComposer.ɵprov = /** @pureOrBreakMyCode */ i0.ɵɵdefineInjectable({ token: DateSuggestionComposer, factory: DateSuggestionComposer.ɵfac });
(function () {
    (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DateSuggestionComposer, [{
            type: Injectable
        }], function () {
        return [{ type: undefined, decorators: [{
                        type: Inject,
                        args: [SUGGESTION_STRATEGY_MAP]
                    }] }, { type: i0.Injector }];
    }, null);
})();

function endOfDay(date = new Date()) {
    // eslint-disable-next-line @typescript-eslint/no-magic-numbers
    return new Date(date.setHours(23, 59, 59, 999));
}

// eslint-disable-next-line complexity
function shiftDate(interval, inputDate = new Date()) {
    var _a, _b, _c, _d, _e, _f, _g;
    const date = new Date(inputDate);
    const years = date.getFullYear() + ((_a = interval.years) !== null && _a !== void 0 ? _a : 0);
    const months = date.getMonth() + ((_b = interval.months) !== null && _b !== void 0 ? _b : 0);
    const days = date.getDate() + ((_c = interval.days) !== null && _c !== void 0 ? _c : 0);
    const hours = date.getHours() + ((_d = interval.hours) !== null && _d !== void 0 ? _d : 0);
    const minutes = date.getMinutes() + ((_e = interval.minutes) !== null && _e !== void 0 ? _e : 0);
    const seconds = date.getSeconds() + ((_f = interval.seconds) !== null && _f !== void 0 ? _f : 0);
    const milliseconds = date.getMilliseconds() + ((_g = interval.milliseconds) !== null && _g !== void 0 ? _g : 0);
    const convertedDate = new Date(years, months, days, hours, minutes, seconds, milliseconds);
    if (isNotNil(interval === null || interval === void 0 ? void 0 : interval.timeZone)) {
        return new Date(convertedDate.toLocaleString('en-US', { timeZone: interval.timeZone }));
    }
    return convertedDate;
}

function startOfDay(date = new Date()) {
    return new Date(date.setHours(0, 0, 0, 0));
}

const WEEK_LENGTH = 7;
class DateSuggestionCalendarWeekStrategy {
    constructor(dateAdapter) {
        this.dateAdapter = dateAdapter;
    }
    updateIntervalFor(control, { dateFromKey, dateToKey }) {
        const localizedDayOfWeek = (new Date().getDay() + WEEK_LENGTH - this.dateAdapter.getFirstDayOfWeek()) % WEEK_LENGTH;
        control.patchValue({
            [dateFromKey]: startOfDay(shiftDate({ days: -localizedDayOfWeek })),
            [dateToKey]: endOfDay()
        });
    }
}
/** @nocollapse */ DateSuggestionCalendarWeekStrategy.ɵfac = function DateSuggestionCalendarWeekStrategy_Factory(t) { return new (t || DateSuggestionCalendarWeekStrategy)(i0.ɵɵinject(i1.DateAdapter)); };
/** @nocollapse */ DateSuggestionCalendarWeekStrategy.ɵprov = /** @pureOrBreakMyCode */ i0.ɵɵdefineInjectable({ token: DateSuggestionCalendarWeekStrategy, factory: DateSuggestionCalendarWeekStrategy.ɵfac });
(function () {
    (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DateSuggestionCalendarWeekStrategy, [{
            type: Injectable
        }], function () { return [{ type: i1.DateAdapter }]; }, null);
})();

class DateSuggestionFirstDayOfIntervalStrategy {
    updateIntervalFor(control, { dateFromKey, dateToKey }) {
        control.patchValue({
            [dateFromKey]: startOfDay(control.value[dateFromKey]),
            [dateToKey]: endOfDay(control.value[dateFromKey])
        });
    }
}
/** @nocollapse */ DateSuggestionFirstDayOfIntervalStrategy.ɵfac = function DateSuggestionFirstDayOfIntervalStrategy_Factory(t) { return new (t || DateSuggestionFirstDayOfIntervalStrategy)(); };
/** @nocollapse */ DateSuggestionFirstDayOfIntervalStrategy.ɵprov = /** @pureOrBreakMyCode */ i0.ɵɵdefineInjectable({ token: DateSuggestionFirstDayOfIntervalStrategy, factory: DateSuggestionFirstDayOfIntervalStrategy.ɵfac });
(function () {
    (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DateSuggestionFirstDayOfIntervalStrategy, [{
            type: Injectable
        }], null, null);
})();

const DAYS_COUNT = new InjectionToken('Days count for date suggestion');

class DateSuggestionLastDaysOfIntervalStrategy {
    constructor(lastDaysCount) {
        this.lastDaysCount = lastDaysCount;
    }
    updateIntervalFor(control, { dateFromKey, dateToKey }) {
        const daysShiftAgo = -(this.lastDaysCount - 1);
        control.patchValue({
            [dateFromKey]: startOfDay(shiftDate({ days: daysShiftAgo }, control.value[dateToKey])),
            [dateToKey]: endOfDay(control.value[dateToKey])
        });
    }
}
/** @nocollapse */ DateSuggestionLastDaysOfIntervalStrategy.ɵfac = function DateSuggestionLastDaysOfIntervalStrategy_Factory(t) { return new (t || DateSuggestionLastDaysOfIntervalStrategy)(i0.ɵɵinject(DAYS_COUNT)); };
/** @nocollapse */ DateSuggestionLastDaysOfIntervalStrategy.ɵprov = /** @pureOrBreakMyCode */ i0.ɵɵdefineInjectable({ token: DateSuggestionLastDaysOfIntervalStrategy, factory: DateSuggestionLastDaysOfIntervalStrategy.ɵfac });
(function () {
    (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DateSuggestionLastDaysOfIntervalStrategy, [{
            type: Injectable
        }], function () {
        return [{ type: undefined, decorators: [{
                        type: Inject,
                        args: [DAYS_COUNT]
                    }] }];
    }, null);
})();

class DateSuggestionLastFewDaysStrategy {
    constructor(daysCount) {
        this.daysCount = daysCount;
    }
    updateIntervalFor(control, { dateFromKey, dateToKey }) {
        const daysShiftAgo = -(this.daysCount - 1);
        control.patchValue({
            [dateFromKey]: startOfDay(shiftDate({ days: daysShiftAgo })),
            [dateToKey]: endOfDay()
        });
    }
}
/** @nocollapse */ DateSuggestionLastFewDaysStrategy.ɵfac = function DateSuggestionLastFewDaysStrategy_Factory(t) { return new (t || DateSuggestionLastFewDaysStrategy)(i0.ɵɵinject(DAYS_COUNT)); };
/** @nocollapse */ DateSuggestionLastFewDaysStrategy.ɵprov = /** @pureOrBreakMyCode */ i0.ɵɵdefineInjectable({ token: DateSuggestionLastFewDaysStrategy, factory: DateSuggestionLastFewDaysStrategy.ɵfac });
(function () {
    (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DateSuggestionLastFewDaysStrategy, [{
            type: Injectable
        }], function () {
        return [{ type: undefined, decorators: [{
                        type: Inject,
                        args: [DAYS_COUNT]
                    }] }];
    }, null);
})();

class DateSuggestionSomeDayAgoStrategy {
    constructor(daysCount) {
        this.daysCount = daysCount;
    }
    updateIntervalFor(control, { dateFromKey, dateToKey }) {
        const day = shiftDate({ days: -this.daysCount });
        control.patchValue({
            [dateFromKey]: startOfDay(day),
            [dateToKey]: endOfDay(day)
        });
    }
}
/** @nocollapse */ DateSuggestionSomeDayAgoStrategy.ɵfac = function DateSuggestionSomeDayAgoStrategy_Factory(t) { return new (t || DateSuggestionSomeDayAgoStrategy)(i0.ɵɵinject(DAYS_COUNT)); };
/** @nocollapse */ DateSuggestionSomeDayAgoStrategy.ɵprov = /** @pureOrBreakMyCode */ i0.ɵɵdefineInjectable({ token: DateSuggestionSomeDayAgoStrategy, factory: DateSuggestionSomeDayAgoStrategy.ɵfac });
(function () {
    (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DateSuggestionSomeDayAgoStrategy, [{
            type: Injectable
        }], function () {
        return [{ type: undefined, decorators: [{
                        type: Inject,
                        args: [DAYS_COUNT]
                    }] }];
    }, null);
})();

const DEFAULT_SUGGESTION_STRATEGY_MAP = {
    ["TODAY" /* TODAY */]: {
        strategy: DateSuggestionSomeDayAgoStrategy,
        providers: [{ provide: DAYS_COUNT, useValue: 0 }]
    },
    ["YESTERDAY" /* YESTERDAY */]: {
        strategy: DateSuggestionSomeDayAgoStrategy,
        providers: [{ provide: DAYS_COUNT, useValue: 1 }]
    },
    ["CALENDAR_WEEK" /* CALENDAR_WEEK */]: { strategy: DateSuggestionCalendarWeekStrategy },
    ["LAST_3_DAYS" /* LAST_3_DAYS */]: {
        strategy: DateSuggestionLastFewDaysStrategy,
        providers: [{ provide: DAYS_COUNT, useValue: 3 }]
    },
    ["LAST_7_DAYS" /* LAST_7_DAYS */]: {
        strategy: DateSuggestionLastFewDaysStrategy,
        providers: [{ provide: DAYS_COUNT, useValue: 7 }]
    },
    ["LAST_60_DAYS" /* LAST_60_DAYS */]: {
        strategy: DateSuggestionLastFewDaysStrategy,
        providers: [{ provide: DAYS_COUNT, useValue: 60 }]
    },
    ["FIRST_DAY_OF_INTERVAL" /* FIRST_DAY_OF_INTERVAL */]: { strategy: DateSuggestionFirstDayOfIntervalStrategy },
    ["LAST_180_DAYS_OF_INTERVAL" /* LAST_180_DAYS_OF_INTERVAL */]: {
        strategy: DateSuggestionLastDaysOfIntervalStrategy,
        providers: [{ provide: DAYS_COUNT, useValue: 180 }]
    }
};

class DateSuggestionModule {
    static forRoot(customSuggestionStrategyMap) {
        return {
            ngModule: DateSuggestionModule,
            providers: [
                DateSuggestionComposer,
                {
                    provide: SUGGESTION_STRATEGY_MAP,
                    useValue: customSuggestionStrategyMap !== null && customSuggestionStrategyMap !== void 0 ? customSuggestionStrategyMap : DEFAULT_SUGGESTION_STRATEGY_MAP
                }
            ]
        };
    }
}
/** @nocollapse */ DateSuggestionModule.ɵfac = function DateSuggestionModule_Factory(t) { return new (t || DateSuggestionModule)(); };
/** @nocollapse */ DateSuggestionModule.ɵmod = /** @pureOrBreakMyCode */ i0.ɵɵdefineNgModule({ type: DateSuggestionModule });
/** @nocollapse */ DateSuggestionModule.ɵinj = /** @pureOrBreakMyCode */ i0.ɵɵdefineInjector({});
(function () {
    (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DateSuggestionModule, [{
            type: NgModule
        }], null, null);
})();

function getToday() {
    return new Date(new Date().setHours(0, 0, 0, 0));
}

function isDateValid(date) {
    return date instanceof Date && Boolean(date.getTime());
}

function isToday(someDate) {
    const today = new Date();
    return (someDate.getDate() === today.getDate() &&
        someDate.getMonth() === today.getMonth() &&
        someDate.getFullYear() === today.getFullYear());
}

function toFormat(value, format) {
    return new DatePipe('en-US').transform(value, format);
}

function toFormatDateTime(time, options = {}) {
    var _a, _b;
    const timeValue = time !== null && time !== void 0 ? time : Date.now();
    const formatValue = (_a = options.format) !== null && _a !== void 0 ? _a : 'dd.MM.yyyy HH:mm:ss';
    return (_b = new DatePipe('en-US').transform(timeValue, formatValue, options.timezone)) !== null && _b !== void 0 ? _b : '';
}

function toISOString(time, defaultValue = '') {
    try {
        return checkValueIsFilled(time) ? new Date(time).toISOString() : defaultValue;
    }
    catch (_a) {
        return defaultValue;
    }
}

function toISOStringWithoutTimezone(inputDate) {
    const date = new Date(inputDate);
    const shiftInMinutes = date.getMinutes() - date.getTimezoneOffset();
    const localDateTime = new Date(date.setMinutes(shiftInMinutes));
    return localDateTime.toISOString().slice(0, -1);
}

function toMilliseconds(seconds) {
    if (seconds instanceof Date) {
        return seconds.getTime();
    }
    // eslint-disable-next-line @typescript-eslint/no-magic-numbers
    return toNumber(seconds === null || seconds === void 0 ? void 0 : seconds.toString()) * 1000;
}

function toPrettyFormat(timestamp) {
    return toFormat(timestamp, 'dd.MM.yyyy HH:mm:ss');
}

function toTimestamp(date, format) {
    const correctDate = dateStringToDate(date);
    return toFormat(correctDate, format);
}

function toUnix(date) {
    if (date instanceof Date) {
        return date.getTime();
    }
    else if (isString(date)) {
        return new Date(date).getTime();
    }
    return date;
}

function toUtc(config = {}) {
    const { fullYear, month, date, hours, minutes, seconds, timeZoneHours } = Object.assign({
        fullYear: new Date().getFullYear(),
        month: new Date().getMonth(),
        date: new Date().getDate(),
        hours: 0,
        minutes: 0,
        seconds: 0,
        // eslint-disable-next-line @typescript-eslint/no-magic-numbers
        timeZoneHours: new Date().getTimezoneOffset() /* TIMEZONE_OFFSET */ / 60 /* ONE_HOUR */
    }, config);
    return new Date(Date.UTC(fullYear, month, date, hours + timeZoneHours, minutes, seconds)).toISOString();
}

/**
 * Generated bundle index. Do not edit.
 */

export { DAYS_COUNT, DEFAULT_SUGGESTION_STRATEGY_MAP, DateSuggestionCalendarWeekStrategy, DateSuggestionComposer, DateSuggestionFirstDayOfIntervalStrategy, DateSuggestionLastDaysOfIntervalStrategy, DateSuggestionLastFewDaysStrategy, DateSuggestionModule, DateSuggestionSomeDayAgoStrategy, SUGGESTION_STRATEGY_MAP, dateStringToDate, endOfDay, getToday, isDateValid, isToday, shiftDate, startOfDay, toFormat, toFormatDateTime, toISOString, toISOStringWithoutTimezone, toMilliseconds, toPrettyFormat, toTimestamp, toUnix, toUtc };
//# sourceMappingURL=angular-ru-cdk-date.mjs.map
