"""
Translation Engine for Hotel MCP Server.

This module provides multilingual support for hotel content with:
- Automatic language detection
- Fallback to default language
- Field-level translation support
- Caching for performance
"""

import logging
from dataclasses import dataclass
from enum import Enum
from typing import Any, Dict, List, Optional

logger = logging.getLogger(__name__)


class SupportedLanguage(Enum):
    """Supported languages for the hotel MCP."""

    SPANISH = "es"
    ENGLISH = "en"
    FRENCH = "fr"
    CATALAN = "ca"


@dataclass
class TranslationConfig:
    """Configuration for translation engine."""

    default_language: SupportedLanguage = SupportedLanguage.SPANISH
    fallback_language: SupportedLanguage = SupportedLanguage.ENGLISH
    translatable_fields: List[str] = None

    def __post_init__(self):
        if self.translatable_fields is None:
            self.translatable_fields = ["name", "description", "title", "content"]


class TranslationEngine:
    """
    Translation engine for multilingual content.

    Handles translation of database records with support for:
    - Multiple languages (ES, EN, FR, CA)
    - Field-level translations
    - Fallback mechanisms
    - Performance optimization
    """

    def __init__(self, config: Optional[TranslationConfig] = None):
        """Initialize the translation engine."""
        self.config = config or TranslationConfig()
        self._translation_cache: Dict[str, Dict[str, Any]] = {}

        logger.info(
            f"Translation engine initialized with default language: {self.config.default_language.value}"
        )

    def get_supported_languages(self) -> List[str]:
        """Get list of supported language codes."""
        return [lang.value for lang in SupportedLanguage]

    def is_language_supported(self, language: str) -> bool:
        """Check if a language is supported."""
        return language in self.get_supported_languages()

    def normalize_language(self, language: Optional[str]) -> str:
        """
        Normalize and validate language code.

        Args:
            language: Language code to normalize

        Returns:
            Normalized language code
        """
        if not language:
            return self.config.default_language.value

        # Handle common variations
        language = language.lower().strip()

        # Map common variations
        language_map = {
            "spa": "es",
            "spanish": "es",
            "español": "es",
            "eng": "en",
            "english": "en",
            "inglés": "en",
            "fre": "fr",
            "french": "fr",
            "français": "fr",
            "francés": "fr",
            "cat": "ca",
            "catalan": "ca",
            "català": "ca",
            "catalán": "ca",
        }

        language = language_map.get(language, language)

        if self.is_language_supported(language):
            return language
        else:
            logger.warning(
                f"Unsupported language '{language}', falling back to {self.config.default_language.value}"
            )
            return self.config.default_language.value

    def _extract_translation_field(
        self, record: Dict[str, Any], field: str, language: str
    ) -> Optional[str]:
        """
        Extract a translated field from a record.

        Tries multiple field naming conventions:
        - field_lang (e.g., name_es, description_en)
        - field.lang (e.g., name.es, description.en)
        - nested object structure
        """
        # Try direct field with language suffix
        lang_field = f"{field}_{language}"
        if lang_field in record and record[lang_field]:
            return record[lang_field]

        # Try nested object structure
        if field in record and isinstance(record[field], dict):
            if language in record[field] and record[field][language]:
                return record[field][language]

        # Try base field if it exists (might be default language)
        if field in record and record[field]:
            return record[field]

        return None

    def translate_record(
        self,
        record: Dict[str, Any],
        target_language: Optional[str] = None,
        fields: Optional[List[str]] = None,
    ) -> Dict[str, Any]:
        """
        Translate a database record to the target language.

        Args:
            record: Database record to translate
            target_language: Target language code
            fields: Specific fields to translate (defaults to config)

        Returns:
            Translated record
        """
        if not record:
            return record

        target_lang = self.normalize_language(target_language)
        fields_to_translate = fields or self.config.translatable_fields

        # Create a copy of the record
        translated_record = record.copy()

        for field in fields_to_translate:
            # Try to get translation in target language
            translated_value = self._extract_translation_field(
                record, field, target_lang
            )

            # If not found, try fallback language
            if (
                not translated_value
                and target_lang != self.config.fallback_language.value
            ):
                translated_value = self._extract_translation_field(
                    record, field, self.config.fallback_language.value
                )

            # If still not found, try default language
            if (
                not translated_value
                and target_lang != self.config.default_language.value
            ):
                translated_value = self._extract_translation_field(
                    record, field, self.config.default_language.value
                )

            # Update the record with the translated value
            if translated_value:
                translated_record[field] = translated_value

        # Add metadata about the translation
        translated_record["_translation_meta"] = {
            "target_language": target_lang,
            "translated_fields": fields_to_translate,
            "fallback_used": target_lang != self.config.default_language.value,
        }

        return translated_record

    def translate_records(
        self,
        records: List[Dict[str, Any]],
        target_language: Optional[str] = None,
        fields: Optional[List[str]] = None,
    ) -> List[Dict[str, Any]]:
        """
        Translate a list of database records.

        Args:
            records: List of database records to translate
            target_language: Target language code
            fields: Specific fields to translate

        Returns:
            List of translated records
        """
        if not records:
            return records

        target_lang = self.normalize_language(target_language)

        logger.debug(f"Translating {len(records)} records to {target_lang}")

        return [
            self.translate_record(record, target_lang, fields) for record in records
        ]

    def get_available_translations(
        self, record: Dict[str, Any], field: str
    ) -> List[str]:
        """
        Get list of available translations for a specific field in a record.

        Args:
            record: Database record
            field: Field name to check

        Returns:
            List of available language codes
        """
        available_languages = []

        for lang in self.get_supported_languages():
            if self._extract_translation_field(record, field, lang):
                available_languages.append(lang)

        return available_languages

    def get_translation_completeness(self, record: Dict[str, Any]) -> Dict[str, float]:
        """
        Get translation completeness percentage for each language.

        Args:
            record: Database record to analyze

        Returns:
            Dictionary mapping language codes to completeness percentages
        """
        completeness = {}
        total_fields = len(self.config.translatable_fields)

        if total_fields == 0:
            return completeness

        for lang in self.get_supported_languages():
            translated_fields = 0

            for field in self.config.translatable_fields:
                if self._extract_translation_field(record, field, lang):
                    translated_fields += 1

            completeness[lang] = (translated_fields / total_fields) * 100

        return completeness


# Global translation engine instance
_translation_engine: Optional[TranslationEngine] = None


def get_translation_engine() -> TranslationEngine:
    """Get the global translation engine instance."""
    global _translation_engine
    if _translation_engine is None:
        _translation_engine = TranslationEngine()
    return _translation_engine
