import whisper
import tempfile
import os
import asyncio
import logging
from pathlib import Path

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


class WhisperService:
    _instance = None
    _model    = None

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

    def _load_model(self):
        if self._model is None:
            model_size = os.getenv("MODEL_SIZE", "small")
            models_dir = Path("/app/models")
            models_dir.mkdir(exist_ok=True)
            logger.info(f"Loading Whisper model: {model_size}")
            self._model = whisper.load_model(model_size, download_root=str(models_dir))
            logger.info("Whisper model loaded.")
        return self._model

    async def transcribe(self, audio_bytes: bytes, language: str | None = None) -> dict:
        """
        Transcrie audio bytes. Rulează Whisper în executor thread pentru a nu bloca event loop.
        """
        def _run():
            model = self._load_model()
            suffix = ".ogg"
            with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as tmp:
                tmp.write(audio_bytes)
                tmp_path = tmp.name

            try:
                options = {}
                if language:
                    options["language"] = language

                result = model.transcribe(tmp_path, **options)

                return {
                    "text": result["text"].strip(),
                    "language": result.get("language", "unknown"),
                    "segments": [
                        {
                            "start": round(s["start"], 2),
                            "end":   round(s["end"], 2),
                            "text":  s["text"].strip(),
                        }
                        for s in result.get("segments", [])
                    ],
                }
            finally:
                os.unlink(tmp_path)

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