import { formatMoney } from "@vmall/shared"; import type { Currency } from "@vmall/shared"; export function usePrice() { const { currency } = usePrefs(); const { locale } = useI18n(); const { $api } = useNuxtApp(); const currencies = useState("mall-currencies", () => []); const cache = useState>("mall-price-cache", () => new Map()); const currencyRequest = useState | null>("mall-currency-request", () => null); async function ensureCurrencies(): Promise { if (currencies.value.length > 0) return currencies.value; if (!currencyRequest.value) { currencyRequest.value = $api.listCurrencies().then((list) => { currencies.value = list; return list; }).finally(() => { currencyRequest.value = null; }); } return currencyRequest.value; } function exponentFor(code: string): number { return currencies.value.find((item) => item.code === code)?.exponent ?? 2; } async function convertAmount(amountMinor: number, from: string, to = currency.value): Promise { if (from === to) return amountMinor; const key = `${amountMinor}:${from}:${to}`; const cached = cache.value.get(key); if (cached !== undefined) return cached; const converted = await $api.convert(amountMinor, from, to); cache.value.set(key, converted.amount_minor); return converted.amount_minor; } async function formatPrice(amountMinor: number, from: string, to = currency.value): Promise { await ensureCurrencies(); const amount = await convertAmount(amountMinor, from, to); return formatMoney(amount, to, exponentFor(to), locale.value); } async function formatAmount(amountMinor: number, code: string): Promise { await ensureCurrencies(); return formatMoney(amountMinor, code, exponentFor(code), locale.value); } return { currency, currencies, cache, ensureCurrencies, exponentFor, convertAmount, formatPrice, formatAmount, }; }