# Copyright (C) 2025 AIDC-AI
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#     http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
International language support for Pixelle-Video Web UI
"""

import json
import locale
from pathlib import Path
from typing import Dict, Optional

from loguru import logger

_locales: Dict[str, dict] = {}
_current_language: str = "en_US"  # Default fallback to English


def load_locales() -> Dict[str, dict]:
    """Load all locale files from locales directory"""
    global _locales
    
    locales_dir = Path(__file__).parent / "locales"
    
    if not locales_dir.exists():
        logger.warning(f"Locales directory not found: {locales_dir}")
        return _locales
    
    for json_file in locales_dir.glob("*.json"):
        lang_code = json_file.stem
        try:
            with open(json_file, "r", encoding="utf-8") as f:
                _locales[lang_code] = json.load(f)
            logger.debug(f"Loaded locale: {lang_code}")
        except Exception as e:
            logger.error(f"Failed to load locale {lang_code}: {e}")
    
    logger.info(f"Loaded {len(_locales)} locales: {list(_locales.keys())}")
    return _locales


def set_language(lang_code: str):
    """Set current language"""
    global _current_language
    if lang_code in _locales:
        _current_language = lang_code
        logger.debug(f"Language set to: {lang_code}")
    else:
        logger.warning(f"Language {lang_code} not found, keeping {_current_language}")


def get_language() -> str:
    """Get current language"""
    return _current_language


def tr(key: str, fallback: Optional[str] = None, **kwargs) -> str:
    """
    Translate a key to current language
    
    Args:
        key: Translation key (e.g., "app.title")
        fallback: Fallback text if key not found
        **kwargs: Format parameters for string interpolation
    
    Returns:
        Translated text
    
    Example:
        tr("app.title")  # => "Pixelle-Video"
        tr("error.missing_field", field="API Key")  # => "请填写 API Key"
    """
    locale = _locales.get(_current_language, {})
    translations = locale.get("t", {})
    
    result = translations.get(key)
    
    if result is None:
        # Try fallback parameter
        if fallback is not None:
            result = fallback
        # Try English fallback
        elif _current_language != "en_US" and "en_US" in _locales:
            en_locale = _locales["en_US"]
            result = en_locale.get("t", {}).get(key)
        
        # Last resort: return the key itself
        if result is None:
            result = key
            logger.debug(f"Translation missing: {key}")
    
    # Apply string interpolation if kwargs provided
    if kwargs:
        try:
            result = result.format(**kwargs)
        except (KeyError, ValueError) as e:
            logger.warning(f"Failed to format translation '{key}': {e}")
    
    return result


def get_language_name(lang_code: Optional[str] = None) -> str:
    """Get display name of a language"""
    if lang_code is None:
        lang_code = _current_language
    
    locale = _locales.get(lang_code, {})
    return locale.get("language_name", lang_code)


def get_available_languages() -> Dict[str, str]:
    """Get all available languages with their display names"""
    return {
        code: locale.get("language_name", code)
        for code, locale in _locales.items()
    }


def detect_system_language() -> str:
    """
    Detect system/OS language and return the best matching locale code.
    Falls back to English if no match found.
    
    This is designed for self-hosted scenarios where the server and browser
    are typically on the same machine.
    
    Returns:
        Language code (e.g., "zh_CN", "en_US")
    """
    try:
        import os
        import platform
        import subprocess
        
        system_locale = None
        
        # Method 1: macOS-specific detection (most reliable for macOS)
        if platform.system() == "Darwin":  # macOS
            try:
                # Get AppleLocale which reflects system language preference
                result = subprocess.run(
                    ["defaults", "read", "-g", "AppleLocale"],
                    capture_output=True,
                    text=True,
                    timeout=2
                )
                if result.returncode == 0:
                    system_locale = result.stdout.strip()
                    logger.debug(f"System locale from macOS AppleLocale: {system_locale}")
            except Exception as e:
                logger.debug(f"macOS AppleLocale detection failed: {e}")
            
            # Fallback: try AppleLanguages
            if not system_locale:
                try:
                    result = subprocess.run(
                        ["defaults", "read", "-g", "AppleLanguages"],
                        capture_output=True,
                        text=True,
                        timeout=2
                    )
                    if result.returncode == 0:
                        # Parse array output like: ( "zh-Hans-CN", "en-CN" )
                        output = result.stdout.strip()
                        # Extract first language
                        import re
                        match = re.search(r'"([^"]+)"', output)
                        if match:
                            lang = match.group(1)
                            # Convert zh-Hans-CN to zh_CN
                            if lang.startswith("zh-Hans"):
                                system_locale = "zh_CN"
                            elif lang.startswith("zh-Hant"):
                                system_locale = "zh_TW"
                            else:
                                system_locale = lang.replace("-", "_")
                            logger.debug(f"System locale from macOS AppleLanguages: {system_locale}")
                except Exception as e:
                    logger.debug(f"macOS AppleLanguages detection failed: {e}")
        
        # Method 2: Get from environment locale (cross-platform)
        if not system_locale:
            try:
                system_locale = locale.getdefaultlocale()[0]
                logger.debug(f"System locale from getdefaultlocale(): {system_locale}")
            except Exception as e:
                logger.debug(f"getdefaultlocale() failed: {e}")
        
        # Method 3: Get from current locale
        if not system_locale:
            try:
                system_locale = locale.getlocale()[0]
                logger.debug(f"System locale from getlocale(): {system_locale}")
            except Exception as e:
                logger.debug(f"getlocale() failed: {e}")
        
        # Method 4: Try to get from environment variables
        if not system_locale:
            for env_var in ['LC_ALL', 'LC_MESSAGES', 'LANG', 'LANGUAGE']:
                env_value = os.environ.get(env_var)
                if env_value:
                    # Extract language code from formats like "zh_CN.UTF-8"
                    system_locale = env_value.split('.')[0]
                    logger.debug(f"System locale from {env_var}: {system_locale}")
                    break
        
        if system_locale:
            # Normalize the locale string
            # Handle formats: zh_CN, zh-CN, zh_CN.UTF-8, etc.
            system_locale = system_locale.replace('-', '_').split('.')[0]
            
            # Direct match (e.g., "zh_CN")
            for locale_code in _locales.keys():
                if locale_code.lower() == system_locale.lower():
                    logger.info(f"System language matched: {locale_code}")
                    return locale_code
            
            # Partial match (e.g., "zh" matches "zh_CN")
            lang_prefix = system_locale.split('_')[0].lower()
            for locale_code in _locales.keys():
                if locale_code.lower().startswith(lang_prefix):
                    logger.info(f"System language partially matched: {locale_code} (from {system_locale})")
                    return locale_code
        
        logger.info("No system language detected, using fallback")
    except Exception as e:
        logger.warning(f"Failed to detect system language: {e}")
    
    # Fallback to English
    return "en_US"


# Auto-load locales on import
load_locales()

# Auto-detect and set system language
_detected_language = detect_system_language()
_current_language = _detected_language
logger.info(f"Default language initialized to: {_current_language}")

