"""
Language code handling for wittrans.

SPDX-FileCopyrightText: 2024 Jiri Grönroos <jiri.gronroos@iki.fi>

SPDX-License-Identifier: LGPL-3.0-or-later
"""

import locale

from .language_mappings import (
    iso_639_1,
    iso_639_3,
    iso_639_3_to_1,
    locale_variants,
)


def get_language_name(lang_code: str) -> str:
    """
    Get the full language name from its code.

    Supports:
    1. ISO 639-1 codes (two letters, e.g., "fi", "sv", "en")
    2. ISO 639-2/3 codes (three letters, e.g., "fin", "swe", "eng")
    3. GNU C library locale codes (e.g., "fi_FI.utf8", "zh_CN", "pt_BR")

    Args:
        lang_code: Language code (ISO 639-1, ISO 639-2/3, or full locale code)

    Returns:
        Full language name, or "Unknown (code)" if not found
    """
    # Normalize the input code
    normalized_code = lang_code.lower().strip()

    # Split the code into parts (e.g., "fi_FI.utf8" -> ["fi", "FI", "utf8"])
    parts = normalized_code.split(".")
    locale_parts = parts[0].split("_")
    base_lang = locale_parts[0]

    # 1. Check for known locale variants first
    if len(locale_parts) > 1:
        variant_code = "_".join(locale_parts[:2]).lower()
        if variant_code in locale_variants:
            return locale_variants[variant_code]

    # 2. Check for two-letter ISO 639-1 code
    if len(base_lang) == 2:
        if base_lang in iso_639_1:
            return iso_639_1[base_lang]

    # 3. Check for three-letter ISO 639-2/3 code
    elif len(base_lang) == 3:
        # First try direct mapping for three-letter codes
        if base_lang in iso_639_3:
            return iso_639_3[base_lang]
        # Then try converting to two-letter code
        two_letter = iso_639_3_to_1.get(base_lang)
        if two_letter and two_letter in iso_639_1:
            return iso_639_1[two_letter]

    # 4. Try the locale system as fallback
    try:
        current_locale = locale.getlocale()
        try:
            locale.setlocale(locale.LC_ALL, normalized_code)
            if hasattr(locale, "LANGNAME"):
                language_name = locale.nl_langinfo(locale.LANGNAME)
                if language_name and language_name.strip():
                    return language_name.title()
        except (locale.Error, AttributeError):
            pass
        finally:
            try:
                locale.setlocale(locale.LC_ALL, current_locale)
            except locale.Error:
                locale.setlocale(locale.LC_ALL, "")
    except Exception:
        pass

    # 5. Last resort: return unknown
    return f"Unknown ({normalized_code})"
