import { useRegionStore } from '~/stores/region' /** * 🌍 useFormatter Composable * * Provides locale-aware formatting utilities for numbers, currencies, dates, * and percentages. Uses the active region configuration from the RegionStore * to determine the appropriate locale, currency, and timezone. * * Falls back to 'en-EU' locale and 'EUR' currency if no region is configured. */ export function useFormatter() { const regionStore = useRegionStore() /** * Format a number according to the active locale. * Example: 1234567.89 → "1,234,567.89" (en) or "1 234 567,89" (hu) */ function formatNumber(value: number, options?: Intl.NumberFormatOptions): string { const locale = regionStore.activeLocale || 'en-EU' try { return new Intl.NumberFormat(locale, options).format(value) } catch { return new Intl.NumberFormat('en-EU', options).format(value) } } /** * Format a currency value according to the active region's currency and locale. * Example: 1234.50 → "€1,234.50" (EUR/en) or "3 456 Ft" (HUF/hu) */ function formatCurrency( value: number, currency?: string, options?: Intl.NumberFormatOptions, ): string { const locale = regionStore.activeLocale || 'en-EU' const curr = currency || regionStore.activeCurrency || 'EUR' try { return new Intl.NumberFormat(locale, { style: 'currency', currency: curr, minimumFractionDigits: 2, maximumFractionDigits: 2, ...options, }).format(value) } catch { return `${value.toFixed(2)} ${curr}` } } /** * Format a date according to the active locale and timezone. * Example: 2026-06-24 → "24/06/2026" (en-GB) or "2026. 06. 24." (hu-HU) */ function formatDate( date: Date | string | number, options?: Intl.DateTimeFormatOptions, ): string { const locale = regionStore.activeLocale || 'en-EU' const timezone = regionStore.activeTimezone || 'Europe/Brussels' const d = typeof date === 'string' || typeof date === 'number' ? new Date(date) : date try { return new Intl.DateTimeFormat(locale, { timezone, year: 'numeric', month: '2-digit', day: '2-digit', ...options, }).format(d) } catch { return d.toLocaleDateString('en-GB') } } /** * Format a datetime with time according to the active locale and timezone. * Example: "2026-06-24T14:30:00Z" → "24/06/2026, 16:30" (hu-HU/Budapest) */ function formatDateTime( date: Date | string | number, options?: Intl.DateTimeFormatOptions, ): string { const locale = regionStore.activeLocale || 'en-EU' const timezone = regionStore.activeTimezone || 'Europe/Brussels' const d = typeof date === 'string' || typeof date === 'number' ? new Date(date) : date try { return new Intl.DateTimeFormat(locale, { timezone, year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', ...options, }).format(d) } catch { return d.toLocaleString('en-GB') } } /** * Format a percentage value. * Example: 27 → "27%" or 27.5 → "27,5%" (hu) */ function formatPercent( value: number, options?: Intl.NumberFormatOptions, ): string { const locale = regionStore.activeLocale || 'en-EU' try { return new Intl.NumberFormat(locale, { style: 'percent', minimumFractionDigits: 0, maximumFractionDigits: 1, ...options, }).format(value / 100) } catch { return `${value}%` } } /** * Calculate price including VAT for the active region. * VAT rate comes from the active region's default_vat_rate. */ function calculatePriceWithVat( netPrice: number, vatRate?: number, ): { net: number; vat: number; gross: number; vatRate: number } { const rate = vatRate ?? regionStore.activeVatRate ?? 0 const vat = netPrice * (rate / 100) const gross = netPrice + vat return { net: netPrice, vat, gross, vatRate: rate } } /** * Format a price range with VAT breakdown. * Example: (100, 27) → "Net: €100.00 | VAT: €27.00 (27%) | Gross: €127.00" */ function formatPriceWithVat( netPrice: number, vatRate?: number, currency?: string, ): string { const { net, vat, gross, vatRate: rate } = calculatePriceWithVat(netPrice, vatRate) const curr = currency || regionStore.activeCurrency || 'EUR' return `Net: ${formatCurrency(net, curr)} | VAT: ${formatCurrency(vat, curr)} (${rate}%) | Gross: ${formatCurrency(gross, curr)}` } return { formatNumber, formatCurrency, formatDate, formatDateTime, formatPercent, calculatePriceWithVat, formatPriceWithVat, } }