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

<Meta title='@dxtmisha/vi/functional-basic/Classes/GeoPhone - Mặt nạ điện thoại'/>

# Lớp GeoPhone

Lớp chuyên biệt để lưu trữ và xử lý mặt nạ số điện thoại quốc tế. Cung cấp cơ chế xác định quốc gia theo chuỗi số điện thoại, định dạng số thô thành mặt nạ được bản địa hóa và quản lý bản đồ mã điện thoại phức tạp dựa trên cây tiền tố (Trie). Lớp này được tích hợp chặt chẽ với dữ liệu địa lý `Geo`, cho phép tự động xác định mặt nạ dựa trên ngôn ngữ hiện tại của người dùng hoặc mã quốc gia được cung cấp.

## Tính năng chính

- **Khớp tự động** — Tự động xác định quốc gia và mẫu mặt nạ phù hợp thông qua tìm kiếm đệ quy trong cây tiền tố.
- **Tối ưu hóa cây tiền tố** — Sử dụng cấu trúc `map` chuyên biệt (Trie) để tìm kiếm hiệu suất cao.
- **Bình thường hóa thông minh** — Tự động xử lý các biến thể quay số khu vực như số 0 ở đầu hoặc tiền tố quốc gia.
- **Định dạng tiêu chuẩn** — Chuyển đổi các chuỗi số thô thành định dạng dễ đọc.

## Cách sử dụng cơ bản

Bạn có thể sử dụng các phương thức tĩnh của lớp để xác định nhanh quốc gia theo số điện thoại hoặc định dạng.

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

// Xác định quốc gia theo số điện thoại
const info = GeoPhone.getByPhone('84901234567')
console.log(info.item?.value) // 'VN'

// Định dạng theo mặt nạ
const formatted = GeoPhone.toMask('901234567', ['+** (***) ***-***'])
console.log(formatted) // '+84 (901) 234-567'
```

## Các phương thức

### Thông tin

- `getList(): GeoPhoneValue[]` — Trả về danh sách phẳng đầy đủ, đã được sắp xếp của tất cả dữ liệu meta điện thoại quốc tế.
- `getMap(): Record<string, GeoPhoneMap>` — Trả về nút gốc của cây tiền tố nội bộ được sử dụng để tìm kiếm.

### Lựa chọn

- `get(code: string): GeoPhoneValue | undefined` — Lấy dữ liệu meta điện thoại liên kết với một mã quốc gia cụ thể.
- `getByPhone(phone: string): GeoPhoneMapInfo` — Phân tích chuỗi số điện thoại để trích xuất thông tin và mặt nạ phù hợp.
- `getByCode(code: string): GeoPhoneMap | undefined` — Trả về thông tin mặt nạ đầy đủ cho một mã nhất định.

### Phụ trợ

- `toMask(phone: string, masks?: string[]): string | undefined` — Chuyển đổi chuỗi số điện thoại thô thành phiên bản đã định dạng.
- `removeZero(phone: string): string` — Bình thường hóa biểu diễn nội bộ của số bằng cách loại bỏ các số 0 ở đầu hoặc điều chỉnh tiền tố khu vực.

## Kiểu dữ liệu

### `GeoPhoneValue`
Cấu trúc siêu dữ liệu cơ bản cho cấu hình điện thoại của mỗi quốc gia:
- `phone: number` — Mã điện thoại quốc gia (ví dụ: `84`).
- `within: number` — Mã quy tắc gọi nội bộ (dùng để chọn ký tự đặc biệt trong mặt nạ).
- `mask: string[]` — Mảng các mẫu mặt nạ được gán cho quốc gia.
- `value: string` — Mã định danh quốc gia (ISO 3166).

### `GeoPhoneMap`
Một nút trong cây tiền tố nội bộ (Trie) được sử dụng để tìm kiếm:
- `items: GeoPhoneValue[]` — Danh sách tất cả các mục có sẵn trong nhánh này của cây.
- `info: GeoPhoneValue | undefined` — Dữ liệu meta điện thoại nếu nút hiện tại là một mã đầy đủ.
- `value: string | undefined` — Mã định danh quốc gia cho nút này.
- `mask: string[]` — Mảng các mặt nạ với các ký tự nội bộ đã được thay thế (`~`, `=`, `$`).
- `maskFull: string[]` — Mặt nạ đầy đủ bao gồm cả mã quốc tế.
- `next: Record<string, GeoPhoneMap>` — Con trỏ đến các chữ số tiếp theo trong cây tìm kiếm.

### `GeoPhoneMapInfo`
Kết quả của phương thức tìm kiếm `getByPhone`:
- `item?: GeoPhoneMap` — Nút cây tìm thấy với thông tin quốc gia và mặt nạ.
- `phone?: string` — Phần còn lại của số sau khi tách mã quốc gia.

## Ví dụ

### Logic ký tự nội bộ (Within)
Logic nội bộ của lớp sẽ thay thế dấu "sao" đầu tiên trong mặt nạ bằng một ký tự đặc biệt tùy thuộc vào quy tắc khu vực:
- `~` — cho Nga (mã nội bộ 8).
- `=` — cho các khu vực mặc định/khác (ví dụ: Việt Nam, Hoa Kỳ).

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

### Nhiều mặt nạ
```javascript
const masks = ['+** (***) ***-***', '+** (***) ***-**-**']
console.log(GeoPhone.toMask('84901234567', masks)) // 11 số -> '+84 (901) 234-567'
```
