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

<Meta title='@dxtmisha/ru/functional-basic/Classes/GeoPhone - Маски телефонов'/>

# Класс GeoPhone

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

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

- **Автоматическое сопоставление** — динамически определяет подходящую страну и паттерн маски через рекурсивный поиск по префиксному дереву.
- **Оптимизация дерева префиксов** — использует специализированную структуру `map` (Trie) для высокопроизводительного поиска.
- **Интеллектуальная нормализация** — автоматически обрабатывает региональные вариации набора, такие как ведущие нули или национальные префиксы.
- **Стандартизированное форматирование** — преобразует сырые числовые строки в читаемые форматы.

## Базовое использование

Вы можете использовать статические методы класса для быстрой идентификации страны по номеру телефона или форматирования.

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

// Идентификация страны по номеру
const info = GeoPhone.getByPhone('79001234567')
console.log(info.item?.value) // 'RU'

// Форматирование по маске
const formatted = GeoPhone.toMask('9001234567', ['+* (***) ***-**-**'])
console.log(formatted) // '+7 (900) 123-45-67'
```

## Методы

### Информация

- `getList(): GeoPhoneValue[]` — Возвращает полный отсортированный плоский список всех зарегистрированных метаданных международных телефонов.
- `getMap(): Record<string, GeoPhoneMap>` — Возвращает корневой узел внутреннего префиксного дерева для поиска.

### Выбор

- `get(code: string): GeoPhoneValue | undefined` — Извлекает метаданные телефона, связанные с конкретным кодом страны.
- `getByPhone(phone: string): GeoPhoneMapInfo` — Анализирует строку номера телефона для извлечения информации и подходящей маски.
- `getByCode(code: string): GeoPhoneMap | undefined` — Возвращает полную информацию о маске, включая узел дерева поиска для заданного кода.

### Вспомогательные методы

- `toMask(phone: string, masks?: string[]): string | undefined` — Преобразует сырую числовую строку телефона в отформатированную версию.
- `removeZero(phone: string): string` — Стандартизирует внутреннее представление номера, удаляя ведущие нули или корректируя региональные префиксы.

## Типы данных

### `GeoPhoneValue`
Базовая структура метаданных для конфигурации телефона каждой страны:
- `phone: number` — Телефонный код страны (например, `7`).
- `within: number` — Код внутреннего правила набора (используется для выбора спецсимвола в маске).
- `mask: string[]` — Массив паттернов масок, закрепленных за страной.
- `value: string` — Идентификатор страны (ISO 3166).

### `GeoPhoneMap`
Узел внутреннего префиксного дерева (Trie), используемый для поиска:
- `items: GeoPhoneValue[]` — Список всех элементов, доступных в данной ветви дерева.
- `info: GeoPhoneValue | undefined` — Метаданные телефона, если текущий узел является завершенным кодом.
- `value: string | undefined` — Идентификатор страны для данного узла.
- `mask: string[]` — Массив масок с подставленными спецсимволами (`~`, `=`, `$`).
- `maskFull: string[]` — Полные маски, включая международный код.
- `next: Record<string, GeoPhoneMap>` — Указатели на следующие цифры номера в дереве поиска.

### `GeoPhoneMapInfo`
Результат выполнения метода поиска `getByPhone`:
- `item?: GeoPhoneMap` — Найденный узел дерева с информацией о стране и масках.
- `phone?: string` — Оставшаяся часть номера после отделения кода страны.

## Примеры

### Работа со спецсимволами (Within)
Внутренняя логика класса заменяет первую "звездочку" в маске на спецсимвол в зависимости от региональных правил:
- `~` — для России (код внутри страны 8).
- `$` — для некоторых других регионов.

```javascript
const mapInfo = GeoPhone.getByCode('RU')
console.log(mapInfo.mask[0]) // '~ (***) ***-**-**'
```

### Множественные маски
```javascript
const masks = ['+* (***) ***-**-**', '+* (***) ***-***']
console.log(GeoPhone.toMask('79991234567', masks)) // 11 цифр -> '+7 (999) 123-45-67'
console.log(GeoPhone.toMask('7999123456', masks))  // 10 цифр -> '+7 (999) 123-456'
```
