"""Internationalization (i18n) module for Bobi v3.0."""
from __future__ import annotations

import json
import logging
from pathlib import Path
from typing import Any, Optional

from bot import db

logger = logging.getLogger(__name__)

_LOCALES: dict[str, dict[str, str]] = {}
_DEFAULT_LANG = "fa"


def _load_locales() -> None:
    """Load all locale JSON files from the locales directory."""
    locales_dir = Path(__file__).resolve().parent.parent / "locales"
    if not locales_dir.exists():
        logger.warning("Locales directory not found: %s", locales_dir)
        return
    for path in sorted(locales_dir.glob("*.json")):
        lang = path.stem
        try:
            with open(path, encoding="utf-8") as f:
                _LOCALES[lang] = json.load(f)
        except Exception as e:
            logger.error("Failed to load locale %s: %s", path, e)
    logger.info("Loaded %d locales: %s", len(_LOCALES), list(_LOCALES.keys()))


def get_available_languages() -> list[dict[str, str]]:
    """Return list of available languages with metadata."""
    if not _LOCALES:
        _load_locales()
    result = []
    for code, data in _LOCALES.items():
        meta = data.get("__meta__", {})
        result.append({
            "code": code,
            "name": meta.get("name", code),
            "native": meta.get("native", code),
            "direction": meta.get("direction", "ltr"),
        })
    return result


def get_text(key: str, lang: str = _DEFAULT_LANG, **kwargs: Any) -> str:
    """Get a localized text string with optional format variables."""
    if not _LOCALES:
        _load_locales()
    translations = _LOCALES.get(lang, _LOCALES.get(_DEFAULT_LANG, {}))
    text = translations.get(key, key)
    if kwargs:
        try:
            text = text.format(**kwargs)
        except KeyError:
            pass
    return text


async def get_user_lang(user_id: int) -> str:
    """Get a user's preferred language."""
    try:
        lang = await db.get_user_lang(user_id)
        if lang in _LOCALES or not _LOCALES:
            return lang
    except Exception:
        pass
    return _DEFAULT_LANG


async def set_user_lang(user_id: int, lang: str) -> None:
    """Set a user's preferred language."""
    if lang in _LOCALES:
        await db.set_user_lang(user_id, lang)


def t(key: str, lang: str = _DEFAULT_LANG, **kwargs: Any) -> str:
    """Shorthand for get_text."""
    return get_text(key, lang, **kwargs)


def direction(lang: str) -> str:
    """Get text direction for a language."""
    if not _LOCALES:
        _load_locales()
    meta = _LOCALES.get(lang, {}).get("__meta__", {})
    return meta.get("direction", "ltr")


# Load locales on import
_load_locales()
