"""Per-user locale resolution (Phase 11.I).

Reads / writes the ``core.preferred_language`` app-setting at user scope.
Modules should call :func:`get_user_locale` rather than reading user model
attributes directly.

For full locale resolution including calendar/formatting patterns, use
:func:`resolve_locale` from ``simorgh.apps.localization.selectors``.
"""

from __future__ import annotations

from typing import Any

from django.conf import settings

from simorgh.apps.app_settings.registry import (
    SettingDefinition,
    SettingsError,
    register_setting,
)
from simorgh.apps.app_settings.services import resolve, set_value

# Re-export the canonical locale resolver so modules have a single import path.
from simorgh.apps.localization.selectors import resolve_locale

SETTING_KEY = "core.preferred_language"


def _validate_lang(value: Any) -> str:
    if not isinstance(value, str) or not value.strip():
        raise SettingsError("preferred_language must be a non-empty string")
    return value.strip()


register_setting(
    SettingDefinition(
        key=SETTING_KEY,
        type="string",
        default=getattr(settings, "LANGUAGE_CODE", "en"),
        label_key="settings.core.preferred_language",
        scopes=("system", "tenant", "user"),
        validator=_validate_lang,
    )
)


def get_user_locale(user: Any, *, tenant_id: int | None = None) -> str:
    """Return the user's preferred language, falling back to tenant/system."""
    if user is None:
        return resolve(SETTING_KEY, tenant_id=tenant_id)
    user_id = getattr(user, "pk", None) or getattr(user, "id", None)
    return resolve(SETTING_KEY, tenant_id=tenant_id, user_id=user_id)


def set_user_locale(user: Any, lang: str, *, tenant_id: int | None = None) -> None:
    user_id = getattr(user, "pk", None) or getattr(user, "id", None)
    if user_id is None:
        raise ValueError("set_user_locale requires a saved user")
    set_value(
        SETTING_KEY,
        lang,
        scope="user",
        scope_id=str(user_id),
        tenant_id=tenant_id,
        updated_by_id=user_id,
    )


__all__ = ["SETTING_KEY", "get_user_locale", "resolve_locale", "set_user_locale"]
