/** @license MIT | @cube-dev/ui-kit v0.147.0 | Cube Dev Team */
//#region src/i18n/createFormatter.ts
const cache = /* @__PURE__ */ new Map();
function getIntl(kind, Ctor, locale, options) {
	const key = `${locale}|${kind}|${options ? JSON.stringify(options) : ""}`;
	let instance = cache.get(key);
	if (!instance) {
		instance = new Ctor(locale, options);
		cache.set(key, instance);
	}
	return instance;
}
function toDate(value) {
	const date = value instanceof Date ? value : new Date(value);
	return Number.isNaN(date.getTime()) ? null : date;
}
const BYTE_UNITS = [
	"byte",
	"kilobyte",
	"megabyte",
	"gigabyte",
	"terabyte",
	"petabyte"
];
const RELATIVE_DIVISIONS = [
	{
		amount: 60,
		unit: "second"
	},
	{
		amount: 60,
		unit: "minute"
	},
	{
		amount: 24,
		unit: "hour"
	},
	{
		amount: 7,
		unit: "day"
	},
	{
		amount: 4.34524,
		unit: "week"
	},
	{
		amount: 12,
		unit: "month"
	},
	{
		amount: Number.POSITIVE_INFINITY,
		unit: "year"
	}
];
/**
* Builds a bundle of formatting helpers bound to `locale`. Used by both
* `useFormatter()` (locale from React Aria context) and the pure top-level
* helpers (locale from the module mirror). All `Intl.*` instances are memoized.
*/
function createFormatter(locale) {
	const formatDate = (value, options) => {
		const date = toDate(value);
		if (!date) return "";
		return getIntl("date", Intl.DateTimeFormat, locale, {
			dateStyle: "medium",
			...options
		}).format(date);
	};
	const formatTime = (value, options) => {
		const date = toDate(value);
		if (!date) return "";
		return getIntl("date", Intl.DateTimeFormat, locale, {
			timeStyle: "short",
			...options
		}).format(date);
	};
	const formatDateTime = (value, options) => {
		const date = toDate(value);
		if (!date) return "";
		return getIntl("date", Intl.DateTimeFormat, locale, {
			dateStyle: "medium",
			timeStyle: "short",
			...options
		}).format(date);
	};
	const formatRelativeTime = (value, options) => {
		const date = toDate(value);
		if (!date) return "";
		const now = options?.now != null ? toDate(options.now) : /* @__PURE__ */ new Date();
		if (!now) return "";
		const rtf = getIntl("relative", Intl.RelativeTimeFormat, locale, {
			numeric: options?.numeric ?? "auto",
			style: options?.style ?? "long"
		});
		let duration = (date.getTime() - now.getTime()) / 1e3;
		for (const division of RELATIVE_DIVISIONS) {
			if (Math.abs(duration) < division.amount) return rtf.format(Math.round(duration), division.unit);
			duration /= division.amount;
		}
		return rtf.format(Math.round(duration), "year");
	};
	const formatNumber = (value, options) => getIntl("number", Intl.NumberFormat, locale, options).format(value);
	const formatCurrency = (value, options) => {
		const { currency = "USD", ...rest } = options ?? {};
		return getIntl("number", Intl.NumberFormat, locale, {
			style: "currency",
			currency,
			...rest
		}).format(value);
	};
	const formatPercent = (value, options) => getIntl("number", Intl.NumberFormat, locale, {
		style: "percent",
		...options
	}).format(value);
	const formatBytes = (value, options) => {
		const sign = value < 0 ? -1 : 1;
		let bytes = Math.abs(value);
		let unitIndex = 0;
		while (bytes >= 1e3 && unitIndex < BYTE_UNITS.length - 1) {
			bytes /= 1e3;
			unitIndex++;
		}
		return getIntl("number", Intl.NumberFormat, locale, {
			style: "unit",
			unit: BYTE_UNITS[unitIndex],
			unitDisplay: options?.unitDisplay ?? "short",
			minimumFractionDigits: options?.minimumFractionDigits ?? 0,
			maximumFractionDigits: options?.maximumFractionDigits ?? (unitIndex === 0 ? 0 : 1)
		}).format(sign * bytes);
	};
	const formatList = (items, options) => getIntl("list", Intl.ListFormat, locale, options).format(items);
	return {
		locale,
		formatDate,
		formatTime,
		formatDateTime,
		formatRelativeTime,
		formatNumber,
		formatCurrency,
		formatPercent,
		formatBytes,
		formatList
	};
}

//#endregion
export { createFormatter };
//# sourceMappingURL=createFormatter.js.map