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

<Meta title='@dxtmisha/functional/en/Classes/Geo'/>

# Geo Class

Static class for working with geographic data. Provides methods for determining current location, working with country and language codes, and managing time zones with automatic browser-based detection and localStorage caching.

## Key Features

- **Automatic location detection** — determines current country and language based on browser data
- **Country and language code handling** — supports `language-country` format (e.g., `ru-RU`, `en-US`)
- **Time zone management** — getting and setting time zones
- **localStorage caching** — saves user's selected location
- **Alternative code support** — works with various country and language code variants
- **Complete country database** — access to full list of countries with their data
- **Flexible code parsing** — handles full codes, country codes, or language codes separately

## Data Retrieval Methods

### `get`

Returns complete information about the current country.

**Returns:** `GeoItemFull` — full geographic data object

```javascript
import { Geo } from '@dxtmisha/functional'

const currentGeo = Geo.get()
console.log(currentGeo)
// {
//   country: 'US',
//   language: 'en',
//   standard: 'en-US',
//   firstDay: 'Su',
//   countryAlternative: ['USA', 'United States'],
//   languageAlternative: ['eng', 'english']
// }
```

### `getCountry`

Returns current country code.

**Returns:** `string` — ISO country code (e.g., 'US', 'GB', 'RU')

```javascript
const country = Geo.getCountry()
console.log(country) // 'US'
```

### `getLanguage`

Returns current language code.

**Returns:** `string` — ISO language code (e.g., 'en', 'ru', 'fr')

```javascript
const language = Geo.getLanguage()
console.log(language) // 'en'
```

### `getStandard`

Returns full format according to standard (language-country).

**Returns:** `string` — standard locale format

```javascript
const standard = Geo.getStandard()
console.log(standard) // 'en-US'
```

### `getFirstDay`

Returns first day of week for current location.

**Returns:** `string` — first day code ('Su' for Sunday, 'Mo' for Monday)

```javascript
const firstDay = Geo.getFirstDay()
console.log(firstDay) // 'Su' (US) or 'Mo' (Europe)
```

### `getLocation`

Returns full format of current location.

**Returns:** `string` — current location in language-country format

```javascript
const location = Geo.getLocation()
console.log(location) // 'en-US'
```

### `getItem`

Returns processed data with current language included.

**Returns:** `GeoItemFull` — geographic data with actual language

```javascript
const item = Geo.getItem()
console.log(item)
// Includes all data plus actual language from browser/settings
```

### `getList`

Returns complete list of available countries.

**Returns:** `GeoItem[]` — array of all supported countries

```javascript
const allCountries = Geo.getList()
console.log(allCountries.length) // 200+ countries
console.log(allCountries[0])
// { country: 'AD', language: 'ca', standard: 'ca-AD', firstDay: 'Mo', ... }
```

## Data Search Methods

### `getByCode`

Returns country data by its code (full, country, or language).

**Parameters:**
- `code?: string` — country code in various formats (optional)

**Returns:** `GeoItemFull` — geographic data for specified code

```javascript
// Full code
const dataFull = Geo.getByCode('en-US')
console.log(dataFull.country) // 'US'

// Country code only
const dataCountry = Geo.getByCode('GB')
console.log(dataCountry.language) // 'en'

// Language code only
const dataLanguage = Geo.getByCode('fr')
console.log(dataLanguage.country) // 'FR'

// Fallback to first country if invalid
const dataDefault = Geo.getByCode('invalid')
console.log(dataDefault) // First country from list
```

### `getByCodeFull`

Returns country data by full language-country code.

**Parameters:**
- `code: string` — string in language-country format

**Returns:** `GeoItem | undefined` — country data or undefined if not found

```javascript
const data = Geo.getByCodeFull('ru-RU')
if (data) {
  console.log(data.country) // 'RU'
  console.log(data.language) // 'ru'
}

// Also supports reverse format
const dataReverse = Geo.getByCodeFull('GB-en')
console.log(dataReverse?.country) // 'GB'
```

### `getByCountry`

Returns country data by country code.

**Parameters:**
- `country: string` — ISO country code

**Returns:** `GeoItem | undefined` — country data or undefined if not found

```javascript
const data = Geo.getByCountry('DE')
if (data) {
  console.log(data.language) // 'de'
  console.log(data.standard) // 'de-DE'
}
```

### `getByLanguage`

Returns country data by language code.

**Parameters:**
- `language: string` — ISO language code

**Returns:** `GeoItem | undefined` — country data or undefined if not found

```javascript
const data = Geo.getByLanguage('es')
if (data) {
  console.log(data.country) // 'ES'
  console.log(data.standard) // 'es-ES'
}
```

## Configuration Methods

### `set`

Sets new location and saves it to localStorage.

**Parameters:**
- `code?: string` — location code in various formats (optional)

**Returns:** `Geo` — class reference for chaining

```javascript
// Set by full code
Geo.set('fr-FR')

// Set by country code
Geo.set('IT')

// Set by language code
Geo.set('ja')

// Chaining
Geo.set('de-DE').setTimezone(-60)
```

### `setTimezone`

Sets time zone offset.

**Parameters:**
- `timezone: number` — time zone offset in minutes

**Returns:** `Geo` — class reference for chaining

```javascript
// Set UTC+3 (Moscow time)
Geo.setTimezone(-180)

// Set UTC-5 (New York time)
Geo.setTimezone(300)

// Chaining
Geo.setTimezone(-60).set('de-DE')
```

## Utility Methods

### `toCountry`

Converts country code to uppercase format.

**Parameters:**
- `country: string` — country code in any case

**Returns:** `string` — uppercase country code

```javascript
const country = Geo.toCountry('us')
console.log(country) // 'US'
```

### `toLanguage`

Converts language code to lowercase format.

**Parameters:**
- `language: string` — language code in any case

**Returns:** `string` — lowercase language code

```javascript
const language = Geo.toLanguage('EN')
console.log(language) // 'en'
```

### `toFull`

Converts basic geo item to full format with additional data.

**Parameters:**
- `item: GeoItem` — basic geographic item

**Returns:** `GeoItemFull` — extended geographic data

```javascript
const basicItem = { country: 'US', language: 'en', standard: 'en-US', firstDay: 'Su' }
const fullItem = Geo.toFull(basicItem)
console.log(fullItem.countryAlternative) // ['USA', 'United States', ...]
```

## Examples

### Basic Usage

```javascript
import { Geo } from '@dxtmisha/functional'

// Get current location info
console.log('Current country:', Geo.getCountry())
console.log('Current language:', Geo.getLanguage())
console.log('Full location:', Geo.getLocation())
console.log('First day of week:', Geo.getFirstDay())
```

### Setting Custom Location

```javascript
// Set location to Germany
Geo.set('de-DE')

console.log('New country:', Geo.getCountry()) // 'DE'
console.log('New language:', Geo.getLanguage()) // 'de'
console.log('First day:', Geo.getFirstDay()) // 'Mo'
```

### Working with Country Data

```javascript
// Find country by different codes
const russiaByFull = Geo.getByCode('ru-RU')
const russiaByCountry = Geo.getByCode('RU')
const russiaByLanguage = Geo.getByCode('ru')

console.log('All return Russia:', russiaByFull.country) // 'RU'
```

### Building Country Selector

```javascript
// Get all countries for dropdown
const countries = Geo.getList()

const countryOptions = countries.map(country => ({
  value: country.standard,
  label: `${country.language}-${country.country}`,
  country: country.country,
  language: country.language
}))

console.log('Total countries:', countryOptions.length)
```
