import {Meta} from '@storybook/addon-docs/blocks'

<Meta title='@dxtmisha/ru/functional-basic/Classes/GeoIntl - Интернационализация (Intl)'/>

# Класс GeoIntl

Класс `GeoIntl` представляет собой высокоуровневую оптимизированную обертку над нативным браузерным API `Intl`, разработанную специально для интеграции с возможностями геолокации `Geo`. Он предоставляет единый локаль-зависимый интерфейс для форматирования чисел, валют, единиц измерения, дат, времени и географических имен, автоматически управляя определением локали и кэшированием экземпляров.

Класс реализует паттерн **Singleton на уровне локали**, гарантируя создание и кэширование только одного экземпляра для каждого уникального кода локали, что значительно снижает накладные расходы на повторное создание объектов `Intl`.

## Ключевые особенности

- **Кэширование экземпляров** — Автоматическое управление и повторное использование инстансов на основе стандартизированной строки локали.
- **Унифицированный API форматирования** — Упрощает сложные конфигурации `Intl` до понятных высокоуровневых методов.
- **Адаптивная геолокация** — Автоматически подтягивает значения по умолчанию из глобального состояния `Geo`, если локаль не указана явно.
- **Культурные особенности** — Корректно обрабатывает различные конвенции имен, первые дни недели в календарях и правила склонения числительных.

## Инициализация

### `getInstance`

Возвращает кэшированный экземпляр или создает новый для указанного кода локали.

**Параметры:**
- `code?: string` — Стандартизированная строка локали (например, `'ru-RU'`, `'en-US'`). По умолчанию используется `Geo.getLocation()`.

**Возвращает:** `GeoIntl` — Синглтон-экземпляр для запрошенной локали.

```javascript
import { GeoIntl } from '@dxtmisha/functional-basic'

const intl = GeoIntl.getInstance('ru-RU')
const currentIntl = new GeoIntl() // Также использует синглтон-кэш внутри
```

## Методы локализации и географии

- `getLocation(): string` — Возвращает нормализованную строку стандартной локали (например, `'ru-RU'`).
- `getFirstDay(): string` — Возвращает спецификацию первого дня недели для локали (например, `'Mon'`, `'Sun'`).

## Имена и регионы

### `display`

Предоставляет локализованные переводы для языков, регионов и скриптов, используя движок `Intl.DisplayNames`.

**Параметры:**
- `value?: string` — Идентификационный код (например, `'en'`, `'RU'`).
- `typeOptions?` — Строка, представляющая тип отображения (`'language'`, `'region'`, `'script'`), или полный объект `Intl.DisplayNamesOptions`.

**Возвращает:** `string` — Локализованное название.

```javascript
intl.display('en', 'language') // 'английский'
intl.display('DE', 'region')   // 'Германия'
```

### `languageName` / `countryName`

Удобные методы для получения локализованных названий языков и стран.

**Параметры:**
- `value?: string` — Код языка или страны.
- `style?` — Стиль форматирования: `'long'`, `'short'` или `'narrow'`.

**Возвращает:** `string`

### `fullName`

Форматирует полное имя человека в соответствии с культурными традициями текущей локали. Порядок компонентов (Имя-Отчество-Фамилия или Фамилия-Имя-Отчество) определяется полем `nameFormat` в географических данных.

**Параметры:**
- `last: string` — Фамилия.
- `first: string` — Имя.
- `surname?: string` — Отчество (опционально).
- `short?: boolean` — Если `true`, сокращает все части после первой до инициала (например, `Иванов И. И.`).

**Возвращает:** `string`

## Форматирование чисел

### `number`

Форматирует число, используя возможности `Intl.NumberFormat`.

**Параметры:**
- `value: NumberOrString` — Числовое значение для форматирования.
- `options?: Intl.NumberFormatOptions` — Конфигурация десятичных знаков, группировки и т.д.

**Возвращает:** `string`

### `currency`

Специализированный форматер валют с автоматическим размещением символа.

**Параметры:**
- `value: NumberOrString` — Сумма. Также парсит строки с суффиксами валют (например, `'1500 RUB'`).
- `currencyOptions?: string | Intl.NumberFormatOptions` — Код валюты (`'RUB'`) или детальные опции форматирования.
- `numberOnly?: boolean` — Если `true`, возвращает только отформатированные цифры без символа валюты.

**Возвращает:** `string`

```javascript
intl.currency(1500, 'RUB') // '1 500,00 ₽'
intl.currency('1500 USD')  // '1 500,00 $'
```

### `unit` / `sizeFile`

Форматирует числа с единицами измерения. `sizeFile` обеспечивает рекурсивное масштабирование байтов (автоматическое переключение на КБ, МБ, ГБ).

**Параметры (`sizeFile`):**
- `value: NumberOrString` — Размер в байтах.
- `unitOptions?` — Начальная единица измерения (по умолчанию `'byte'`).

**Возвращает:** `string`

### `plural`

Применяет правила склонения числительных с учетом локали.

**Параметры:**
- `value: NumberOrString` — Число.
- `words: string` — Формы слова, разделенные `|`: `one|two|few|many|other|zero`.
- `options?` — `Intl.PluralRulesOptions`.

**Возвращает:** `string` — Отформатированное число, за которым следует правильная словоформа.

## Даты и время

### `date` / `time`

Основной движок форматирования дат, предоставляющий локализованные представления на основе предустановленных пресетов `GeoDate`.

**Параметры:**
- `value: NumberOrStringOrDate` — Входящая дата.
- `type?: GeoDate` — Идентификатор пресета: `'date'`, `'time'`, `'datetime'`, `'full'`, и др.
- `styleOptions?` — Кастомные `Intl.DateTimeFormatOptions` или строка стиля месяца.
- `hour24?: boolean` — Принудительное 24-часовое представление времени.

**Возвращает:** `string`

### `months` / `weekdays`

Возвращает массивы локализованных названий месяцев или дней недели, идеально подходит для заполнения компонентов выбора в UI.

**Возвращает:** `ItemValue<number>[]` — Массив объектов с полями `label` и `value`.

## Относительное время

### `relative`

Вычисляет и форматирует относительную разницу во времени от контрольной точки (сейчас), автоматически выбирая наиболее подходящую единицу измерения.

**Параметры:**
- `value: NumberOrStringOrDate` — Прошедшая или будущая дата.
- `styleOptions?` — Стиль форматирования (например, `'long'`, `'short'`).
- `todayValue?: Date` — Явная точка отсчета (по умолчанию `new Date()`).

**Возвращает:** `string` (например, `'2 часа назад'`, `'через 3 дня'`)

### `relativeLimit`

Комбинированный форматер для относительного и абсолютного времени. Если дата находится в пределах определенного лимита (`limit`) дней, возвращается относительное время; в противном случае происходит переключение на стандартный формат абсолютной даты.

**Возвращает:** `string`

## Сортировка

### `sort`

Сортирует массив элементов, используя локаль-зависимое сравнение через `Intl.Collator`.

**Параметры:**
- `data: T[]` — Целевой массив.
- `compareFn?` — Опциональная функция трансформации для извлечения ключей сортировки из сложных объектов.

**Возвращает:** `T[]` — Отсортированный массив.

```javascript
intl.sort(['яблоко', 'апельсин', 'банан'])
// ['апельсин', 'банан', 'яблоко']
```
