"""ALiCE voice: banners, messages, hints, errors.

All user-facing text lives here so ALiCE speaks with one consistent voice.
Messages use Rich markup for styling.

This module is now a backward-compatible shim that delegates to the active
personality from :mod:`alice_cli.personalities`.  Existing code that does
``from alice_cli import personality`` and calls ``personality.greeting(...)``
continues to work unchanged.
"""

from __future__ import annotations

from alice_cli.personalities import get_active

# Re-export constants that don't change across personalities.
RECOMMENDED_FONTS = ("Source Code Pro", "Fira Code")


# ---------------------------------------------------------------------------
# Dynamic properties — read from the active personality at call time
# ---------------------------------------------------------------------------


class _BannerDescriptor:
    """Lazy descriptor so ``personality.BANNER`` resolves at access time."""

    def __fget__(self) -> str:
        return get_active().banner


_PROPERTY_MAP: dict[str, str] = {
    "BANNER": "banner",
    "SUCCESS_KEY_RETRIEVED": "success_key_retrieved",
    "SUCCESS_CLAUDE_LAUNCH": "success_claude_launch",
    "SUCCESS_AGENT_COMPOSED": "success_agent_composed",
    "HINT_FONT": "hint_font",
    "HINT_EVAL_USAGE": "hint_eval_usage",
    "HINT_CLAUDE_SHORTCUT": "hint_claude_shortcut",
}


def __getattr__(name: str) -> str:
    """Module-level __getattr__ for dynamic constants.

    Allows ``personality.BANNER``, ``personality.SUCCESS_KEY_RETRIEVED``, etc.
    to resolve from the active personality without breaking existing imports.
    """
    attr = _PROPERTY_MAP.get(name)
    if attr is not None:
        return str(getattr(get_active(), attr))
    raise AttributeError(f"module {__name__!r} has no attribute {name!r}")


# ---------------------------------------------------------------------------
# Function shims — delegate to the active personality instance
# ---------------------------------------------------------------------------


def greeting(username: str) -> str:
    return get_active().greeting(username)


def error_no_profile() -> str:
    return get_active().error_no_profile()


def error_sso_expired(profile: str) -> str:
    return get_active().error_sso_expired(profile)


def error_username_extraction(session_name: str) -> str:
    return get_active().error_username_extraction(session_name)


def error_revoked() -> str:
    return get_active().error_revoked()


def error_empty_credential() -> str:
    return get_active().error_empty_credential()


def error_secret_not_found(secret_path: str) -> str:
    return get_active().error_secret_not_found(secret_path)


def error_dependency_missing(name: str, install_hint: str) -> str:
    return get_active().error_dependency_missing(name, install_hint)


def error_python_version(current: str, minimum: str) -> str:
    return get_active().error_python_version(current, minimum)


def error_claude_not_found() -> str:
    return get_active().error_claude_not_found()


def error_no_inference_profile(alias: str) -> str:
    return get_active().error_no_inference_profile(alias)


def error_cheshire_gate_not_configured() -> str:
    return get_active().error_cheshire_gate_not_configured()


def error_quota_exceeded(detail: str) -> str:
    return get_active().error_quota_exceeded(detail)


# --- Status shims ---


def status_detecting_identity() -> str:
    return get_active().status_detecting_identity()


def status_fetching_secret() -> str:
    return get_active().status_fetching_secret()


def status_identity_detected(username: str) -> str:
    return get_active().status_identity_detected(username)


def status_invoking_model(model_id: str) -> str:
    return get_active().status_invoking_model(model_id)


def status_model_ready(model_id: str) -> str:
    return get_active().status_model_ready(model_id)


def status_resolved_profile(alias: str) -> str:
    return get_active().status_resolved_profile(alias)


def status_fetching_models() -> str:
    return get_active().status_fetching_models()


def status_checking_session() -> str:
    return get_active().status_checking_session()


def status_using_api_key(identity: str = "") -> str:
    return get_active().status_using_api_key(identity)


def status_checking_quota() -> str:
    return get_active().status_checking_quota()


# --- Compose shims ---


def compose_greeting() -> str:
    return get_active().compose_greeting()


# --- Quota shims ---


def quota_no_usage(period: str) -> str:
    return get_active().quota_no_usage(period)


def quota_summary(total_tokens: int, request_count: int) -> str:
    return get_active().quota_summary(total_tokens, request_count)


def quota_exceeded(used: int, limit: int) -> str:
    return get_active().quota_exceeded(used, limit)
