"""Client-side i18n (translations) for STARWASTE.

- Default language: English (en)
- Additional languages live in assets/i18n/<lang>.json
- Fallback: missing keys fall back to English, then to provided default.

This module is intentionally lightweight and dependency-free.
"""

from __future__ import annotations

import json
import os
from dataclasses import dataclass
from pathlib import Path
from typing import Any, Optional

from client.settings import get_language as _get_settings_language


def _deep_get(data: dict, key: str) -> Optional[Any]:
    cur: Any = data
    for part in key.split("."):
        if not isinstance(cur, dict):
            return None
        if part not in cur:
            return None
        cur = cur[part]
    return cur


def _load_json(path: Path) -> dict:
    try:
        return json.loads(path.read_text(encoding="utf-8"))
    except Exception:
        return {}


def _normalize_lang(lang: str) -> str:
    lang = (lang or "").strip().lower()
    if not lang:
        return "en"
    # allow cs-CZ, en_US, etc.
    for sep in ("-", "_"):
        if sep in lang:
            lang = lang.split(sep, 1)[0]
            break
    return lang or "en"


def _detect_language() -> str:
    # Default must remain English.
    env = os.getenv("STARWASTE_LANG")
    if env:
        return _normalize_lang(env)

    # User setting (cross-platform settings.json)
    try:
        cfg_lang = _get_settings_language()
        if cfg_lang:
            return _normalize_lang(cfg_lang)
    except Exception:
        pass

    # Optional: respect system locale if explicitly Czech.
    sys_lang = os.getenv("LC_ALL") or os.getenv("LANG") or ""
    sys_lang = _normalize_lang(sys_lang)
    if sys_lang == "cs":
        return "cs"

    return "en"


@dataclass
class I18n:
    base_dir: Path
    language: str = "en"

    def __post_init__(self):
        self.language = _normalize_lang(self.language)
        self._en: dict = {}
        self._active: dict = {}
        self.reload()

    def reload(self) -> None:
        self._en = _load_json(self.base_dir / "en.json")
        if self.language == "en":
            self._active = self._en
        else:
            self._active = _load_json(self.base_dir / f"{self.language}.json")

    def set_language(self, language: str) -> None:
        self.language = _normalize_lang(language)
        self.reload()

    def t(self, key: str, *, default: Optional[str] = None, **fmt: Any) -> str:
        val = _deep_get(self._active, key)
        if val is None:
            val = _deep_get(self._en, key)
        if val is None:
            val = default
        if val is None:
            # last resort: show key (helps debugging)
            val = key
        if not isinstance(val, str):
            val = str(val)

        if fmt:
            try:
                return val.format(**fmt)
            except Exception:
                return val
        return val


_i18n_singleton: Optional[I18n] = None


def get_i18n() -> I18n:
    global _i18n_singleton
    if _i18n_singleton is None:
        base = Path(__file__).resolve().parent.parent / "assets" / "i18n"
        _i18n_singleton = I18n(base_dir=base, language=_detect_language())
    return _i18n_singleton
