private function addCurrencySymbol(string $value, ?string $currency = null): string
    {
        $currency = $currency ?? $this->defaultCurrency;
        $locale = \Locale::getDefault();

        if (!isset(self::$patterns[$locale])) {
            self::$patterns[$locale] = [];
        }

        if (!isset(self::$patterns[$locale][$currency])) {
            $formatter = new \NumberFormatter($locale, \NumberFormatter::CURRENCY);
            $pattern = $formatter->formatCurrency(123.00, $currency);

            // 1=left-position currency, 2=left-space, 3=right-space, 4=left-position currency.
            // With non latin number scripts.
            preg_match(
                '/^([^\s\xc2\xa0]*)([\s\xc2\xa0]*)\p{N}{3}(?:[,.]\p{N}+)?([\s\xc2\xa0]*)([^\s\xc2\xa0]*)$/iu',
                $pattern,
                $matches
            );

            if (!empty($matches[1])) {
                self::$patterns[$locale][$currency] = ['%1$s'.$matches[2].'%2$s', $matches[1]];
            } elseif (!empty($matches[4])) {
                self::$patterns[$locale][$currency] = ['%2$s'.$matches[3].'%1$s', $matches[4]];
            } else {
                throw new \InvalidArgumentException(
                    sprintf('Locale "%s" with currency "%s" does not provide a currency position.', $locale, $currency)
                );
            }
        }

        return sprintf(self::$patterns[$locale][$currency][0], self::$patterns[$locale][$currency][1], $value);
    }