import asyncio
import logging
from services.lang_detector import LangDetector

logger = logging.getLogger("translator-service")

# Mapping limbi suportate pentru Helsinki-NLP
SUPPORTED_PAIRS = {
    ("en", "ro"), ("ro", "en"),
    ("en", "fr"), ("fr", "en"),
    ("en", "de"), ("de", "en"),
    ("en", "es"), ("es", "en"),
    ("en", "it"), ("it", "en"),
    ("en", "pt"), ("pt", "en"),
    ("en", "ru"), ("ru", "en"),
    ("en", "zh"), ("zh", "en"),
    ("en", "ar"), ("ar", "en"),
    ("en", "ja"), ("ja", "en"),
    ("en", "ko"), ("ko", "en"),
    ("en", "tr"), ("tr", "en"),
    ("en", "pl"), ("pl", "en"),
    ("en", "nl"), ("nl", "en"),
    ("en", "uk"), ("uk", "en"),
}


class TranslatorService:
    _instance  = None
    _pipelines = {}

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

    def _get_pipeline(self, source: str, target: str):
        key = (source, target)
        if key in self._pipelines:
            return self._pipelines[key]

        # Dacă nu e pereche directă, traducem prin engleză
        if key not in SUPPORTED_PAIRS:
            return None

        try:
            from transformers import pipeline
            model_name = f"Helsinki-NLP/opus-mt-{source}-{target}"
            logger.info(f"Loading translation model: {model_name}")
            pipe = pipeline("translation", model=model_name, device=-1)  # CPU
            self._pipelines[key] = pipe
            return pipe
        except Exception as e:
            logger.error(f"Failed to load model {model_name}: {e}")
            return None

    async def translate(self, text: str, source: str | None, target: str) -> dict:
        def _run():
            detector = LangDetector()
            src = source
            if not src:
                detected = detector.detect(text[:200])
                src = detected["language"]

            if src == target:
                return {
                    "translated_text": text,
                    "source_lang":     src,
                    "target_lang":     target,
                    "confidence":      1.0,
                }

            # Traducere directă
            pipe = self._get_pipeline(src, target)

            # Dacă nu există pereche directă, traducem prin engleză
            if pipe is None:
                if src != "en" and target != "en":
                    en_result = self._translate_with_pipeline(text, src, "en")
                    final = self._translate_with_pipeline(en_result, "en", target)
                    return {
                        "translated_text": final,
                        "source_lang":     src,
                        "target_lang":     target,
                        "confidence":      None,
                    }
                raise ValueError(f"Perechea {src}→{target} nu este suportată.")

            result = pipe(text, max_length=1024)
            return {
                "translated_text": result[0]["translation_text"],
                "source_lang":     src,
                "target_lang":     target,
                "confidence":      None,
            }

        loop = asyncio.get_event_loop()
        return await loop.run_in_executor(None, _run)

    def _translate_with_pipeline(self, text: str, src: str, tgt: str) -> str:
        pipe = self._get_pipeline(src, tgt)
        if not pipe:
            return text
        return pipe(text, max_length=1024)[0]["translation_text"]
