/**
 * DevExtreme (cjs/localization/intl/date.js)
 * Version: 24.1.7-build-24272-1937
 * Build date: Sat Sep 28 2024
 *
 * Copyright (c) 2012 - 2024 Developer Express Inc. ALL RIGHTS RESERVED
 * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
 */
"use strict";
exports.default = void 0;
var _extend = require("../../core/utils/extend");
var _core = _interopRequireDefault(require("../core"));

function _interopRequireDefault(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    }
}
const SYMBOLS_TO_REMOVE_REGEX = /[\u200E\u200F]/g;
const NARROW_NO_BREAK_SPACE_REGEX = /[\u202F]/g;
const getIntlFormatter = format => date => {
    if (!format.timeZoneName) {
        const year = date.getFullYear();
        const recognizableAsTwentyCentury = String(year).length < 3;
        const safeYearShift = 400;
        const temporaryYearValue = recognizableAsTwentyCentury ? year + safeYearShift : year;
        const utcDate = new Date(Date.UTC(temporaryYearValue, date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()));
        if (recognizableAsTwentyCentury) {
            utcDate.setFullYear(year)
        }
        const utcFormat = (0, _extend.extend)({
            timeZone: "UTC"
        }, format);
        return formatDateTime(utcDate, utcFormat)
    }
    return formatDateTime(date, format)
};
const formattersCache = {};
const getFormatter = format => {
    const key = _core.default.locale() + "/" + JSON.stringify(format);
    if (!formattersCache[key]) {
        formattersCache[key] = new Intl.DateTimeFormat(_core.default.locale(), format).format
    }
    return formattersCache[key]
};

function formatDateTime(date, format) {
    return getFormatter(format)(date).replace(SYMBOLS_TO_REMOVE_REGEX, "").replace(NARROW_NO_BREAK_SPACE_REGEX, " ")
}
const formatNumber = number => new Intl.NumberFormat(_core.default.locale()).format(number);
const getAlternativeNumeralsMap = (() => {
    const numeralsMapCache = {};
    return locale => {
        if (!(locale in numeralsMapCache)) {
            if ("0" === formatNumber(0)) {
                numeralsMapCache[locale] = false;
                return false
            }
            numeralsMapCache[locale] = {};
            for (let i = 0; i < 10; ++i) {
                numeralsMapCache[locale][formatNumber(i)] = i
            }
        }
        return numeralsMapCache[locale]
    }
})();
const normalizeNumerals = dateString => {
    const alternativeNumeralsMap = getAlternativeNumeralsMap(_core.default.locale());
    if (!alternativeNumeralsMap) {
        return dateString
    }
    return dateString.split("").map((sign => sign in alternativeNumeralsMap ? String(alternativeNumeralsMap[sign]) : sign)).join("")
};
const removeLeadingZeroes = str => str.replace(/(\D)0+(\d)/g, "$1$2");
const dateStringEquals = (actual, expected) => removeLeadingZeroes(actual) === removeLeadingZeroes(expected);
const normalizeMonth = text => text.replace("d\u2019", "de ");
const intlFormats = {
    day: {
        day: "numeric"
    },
    date: {
        year: "numeric",
        month: "long",
        day: "numeric"
    },
    dayofweek: {
        weekday: "long"
    },
    longdate: {
        weekday: "long",
        year: "numeric",
        month: "long",
        day: "numeric"
    },
    longdatelongtime: {
        weekday: "long",
        year: "numeric",
        month: "long",
        day: "numeric",
        hour: "numeric",
        minute: "numeric",
        second: "numeric"
    },
    longtime: {
        hour: "numeric",
        minute: "numeric",
        second: "numeric"
    },
    month: {
        month: "long"
    },
    monthandday: {
        month: "long",
        day: "numeric"
    },
    monthandyear: {
        year: "numeric",
        month: "long"
    },
    shortdate: {},
    shorttime: {
        hour: "numeric",
        minute: "numeric"
    },
    shortyear: {
        year: "2-digit"
    },
    year: {
        year: "numeric"
    }
};
Object.defineProperty(intlFormats, "shortdateshorttime", {
    get: function() {
        const defaultOptions = Intl.DateTimeFormat(_core.default.locale()).resolvedOptions();
        return {
            year: defaultOptions.year,
            month: defaultOptions.month,
            day: defaultOptions.day,
            hour: "numeric",
            minute: "numeric"
        }
    }
});
const getIntlFormat = format => "string" === typeof format && intlFormats[format.toLowerCase()];
const monthNameStrategies = {
    standalone: function(monthIndex, monthFormat) {
        const date = new Date(1999, monthIndex, 13, 1);
        const dateString = getIntlFormatter({
            month: monthFormat
        })(date);
        return dateString
    },
    format: function(monthIndex, monthFormat) {
        const date = new Date(0, monthIndex, 13, 1);
        const dateString = normalizeMonth(getIntlFormatter({
            day: "numeric",
            month: monthFormat
        })(date));
        const parts = dateString.split(" ").filter((part => part.indexOf("13") < 0));
        if (1 === parts.length) {
            return parts[0]
        } else if (2 === parts.length) {
            return parts[0].length > parts[1].length ? parts[0] : parts[1]
        }
        return monthNameStrategies.standalone(monthIndex, monthFormat)
    }
};
var _default = exports.default = {
    engine: function() {
        return "intl"
    },
    getMonthNames: function(format, type) {
        const monthFormat = {
            wide: "long",
            abbreviated: "short",
            narrow: "narrow"
        } [format || "wide"];
        type = "format" === type ? type : "standalone";
        return Array.apply(null, new Array(12)).map(((_, monthIndex) => monthNameStrategies[type](monthIndex, monthFormat)))
    },
    getDayNames: function(format) {
        const result = (format => Array.apply(null, new Array(7)).map(((_, dayIndex) => getIntlFormatter({
            weekday: format
        })(new Date(0, 0, dayIndex)))))({
            wide: "long",
            abbreviated: "short",
            short: "narrow",
            narrow: "narrow"
        } [format || "wide"]);
        return result
    },
    getPeriodNames: function() {
        const hour12Formatter = getIntlFormatter({
            hour: "numeric",
            hour12: true
        });
        return [1, 13].map((hours => {
            const hourNumberText = formatNumber(1);
            const timeParts = hour12Formatter(new Date(0, 0, 1, hours)).split(hourNumberText);
            if (2 !== timeParts.length) {
                return ""
            }
            const biggerPart = timeParts[0].length > timeParts[1].length ? timeParts[0] : timeParts[1];
            return biggerPart.trim()
        }))
    },
    format: function(date, format) {
        if (!date) {
            return
        }
        if (!format) {
            return date
        }
        if ("function" !== typeof format && !format.formatter) {
            format = format.type || format
        }
        const intlFormat = getIntlFormat(format);
        if (intlFormat) {
            return getIntlFormatter(intlFormat)(date)
        }
        const formatType = typeof format;
        if (format.formatter || "function" === formatType || "string" === formatType) {
            return this.callBase.apply(this, arguments)
        }
        return getIntlFormatter(format)(date)
    },
    parse: function(dateString, format) {
        let formatter;
        if (format && !format.parser && "string" === typeof dateString) {
            dateString = normalizeMonth(dateString);
            formatter = date => normalizeMonth(this.format(date, format))
        }
        return this.callBase(dateString, formatter || format)
    },
    _parseDateBySimpleFormat: function(dateString, format) {
        dateString = normalizeNumerals(dateString);
        const formatParts = this.getFormatParts(format);
        const dateParts = dateString.split(/\D+/).filter((part => part.length > 0));
        if (formatParts.length !== dateParts.length) {
            return
        }
        const dateArgs = this._generateDateArgs(formatParts, dateParts);
        const constructValidDate = ampmShift => {
            const parsedDate = ((dateArgs, ampmShift) => {
                const hoursShift = ampmShift ? 12 : 0;
                return new Date(dateArgs.year, dateArgs.month, dateArgs.day, (dateArgs.hours + hoursShift) % 24, dateArgs.minutes, dateArgs.seconds)
            })(dateArgs, ampmShift);
            if (dateStringEquals(normalizeNumerals(this.format(parsedDate, format)), dateString)) {
                return parsedDate
            }
        };
        return constructValidDate(false) || constructValidDate(true)
    },
    _generateDateArgs: function(formatParts, dateParts) {
        const currentDate = new Date;
        const dateArgs = {
            year: currentDate.getFullYear(),
            month: currentDate.getMonth(),
            day: currentDate.getDate(),
            hours: 0,
            minutes: 0,
            seconds: 0
        };
        formatParts.forEach(((formatPart, index) => {
            const datePart = dateParts[index];
            let parsed = parseInt(datePart, 10);
            if ("month" === formatPart) {
                parsed -= 1
            }
            dateArgs[formatPart] = parsed
        }));
        return dateArgs
    },
    formatUsesMonthName: function(format) {
        if ("object" === typeof format && !(format.type || format.format)) {
            return "long" === format.month
        }
        return this.callBase.apply(this, arguments)
    },
    formatUsesDayName: function(format) {
        if ("object" === typeof format && !(format.type || format.format)) {
            return "long" === format.weekday
        }
        return this.callBase.apply(this, arguments)
    },
    getTimeSeparator: function() {
        return normalizeNumerals(formatDateTime(new Date(2001, 1, 1, 11, 11), {
            hour: "numeric",
            minute: "numeric",
            hour12: false
        })).replace(/\d/g, "")
    },
    getFormatParts: function(format) {
        if ("string" === typeof format) {
            return this.callBase(format)
        }
        const intlFormat = (0, _extend.extend)({}, intlFormats[format.toLowerCase()]);
        const date = new Date(2001, 2, 4, 5, 6, 7);
        let formattedDate = getIntlFormatter(intlFormat)(date);
        formattedDate = normalizeNumerals(formattedDate);
        return [{
            name: "year",
            value: 1
        }, {
            name: "month",
            value: 3
        }, {
            name: "day",
            value: 4
        }, {
            name: "hours",
            value: 5
        }, {
            name: "minutes",
            value: 6
        }, {
            name: "seconds",
            value: 7
        }].map((part => ({
            name: part.name,
            index: formattedDate.indexOf(part.value)
        }))).filter((part => part.index > -1)).sort(((a, b) => a.index - b.index)).map((part => part.name))
    }
};
module.exports = exports.default;
module.exports.default = exports.default;
