# i18n Rebuild Analysis (PT-BR, EN, ES, RU)

## Current-state findings (before rebuild)

- ACP and `votesystem` used different i18n stacks (`_('free-text')` vs `__('key')`).
- ACP language selection was URL-based, but `votesystem` used `?lang` with separate cookie/session keys.
- Legacy fallback in `helpers/translations.php` collapsed non-EN languages to PT.
- Route entry had hardcoded `/en/login` redirects in `.htaccess`.
- Several templates hardcoded `<html lang="en">`.
- Admin vote balance used fixed BRL strings (`R$`) and fixed DataTables locale (`pt-BR`).

## Rebuild target

- One key-based translation contract (`t()`, `te()`, `__()`, `_e()`).
- Four supported languages at runtime: `pt`, `en`, `es`, `ru`.
- URL-driven language in ACP plus persistence in session/cookie.
- Unified i18n helper shared by ACP and `votesystem`.
- Fallback chain: active language -> EN -> source key.

## Implemented in this rebuild

### 1) Unified i18n foundation

- Added `helpers/i18n.php` with:
  - language normalization (`pt/en/es/ru`)
  - locale metadata resolution
  - catalog loading from `locale/catalogs/*.php`
  - legacy PO merge for ACP texts
  - replacement placeholders (`{name}` and `:name`)
  - URL helper (`localeUrl`)
  - compatibility wrappers for `__`, `_e` and `_` (when available)

- Added catalogs:
  - `locale/catalogs/pt_BR.php`
  - `locale/catalogs/en_US.php`
  - `locale/catalogs/es_ES.php`
  - `locale/catalogs/ru_RU.php`

### 2) Locale metadata and bootstrap unification

- Updated `helpers/locales.php` to exactly:
  - `pt_BR`, `en_US`, `es_ES`, `ru_RU`
- Wired i18n helper from `helpers/settings.php`.
- Updated `public/index.php`:
  - validates normalized language slug
  - persists language (`session + cookie`) through `i18n_bootstrap`
  - keeps login redirects language-aware (`/{lang}/login`)

### 3) Routing entry correction

- Removed forced `/en/login` rewrites from `.htaccess` so default language is controlled by app settings/bootstrap.

### 4) Critical UI hardcoded cleanup

- Dynamic `html lang` in:
  - `helpers/template.php`
  - `views/login.php`
  - `views/404.php`
  - `views/reset-password.php`
- Replaced hardcoded server-status labels (`Login`, `Game`) in `views/common/header.php` with translation keys.
- Made `admin/vote-balance` locale-aware:
  - currency symbol/prefix from i18n keys
  - DataTables locale URL by selected language
  - modal labels/messages moved to i18n-aware keys

### 5) votesystem alignment

- Replaced custom dictionary engine in `votesystem/i18n.php` with shared ACP helper.
- Updated `votesystem/index.php`, `votesystem/vote.php`, `votesystem/totals.php`, `votesystem/ranking.php` to use unified i18n bootstrap.
- Added RU option in votesystem language selector.
- Fixed JS placeholder mismatch in countdown replacements (`:hh/:mm/:ss`).

## Remaining migration scope (non-blocking for foundation)

- Convert remaining ACP free-text `_('...')` usage into semantic keys (`module.section.label`) incrementally.
- Expand `locale/catalogs/*` with complete business glossary for all screens.
- Add automated CI check to fail build when key coverage diverges across locales.
- Normalize old Gettext artifacts (`locale/*/messages.po`) once key migration is 100% complete.

## QA checklist executed for this phase

- Language switching path and persistence wiring reviewed in `public/index.php`.
- Fallback logic verified in helper implementation (`active -> en -> key`).
- Critical templates now emit dynamic `html lang`.
- Votesystem and ACP now share same i18n state source (`acp_lang` + session).
