from __future__ import annotations

import logging
from typing import Optional

import numpy as np

logger = logging.getLogger(__name__)


class ASRService:
    def __init__(self) -> None:
        self._model = None
        self._post = None
        self._ready = False
        self._attempted = False
        self._init_error: Optional[str] = None

    def _ensure_loaded(self) -> None:
        if self._ready or self._attempted:
            return
        self._attempted = True
        try:
            from funasr import AutoModel
            from funasr.utils.postprocess_utils import rich_transcription_postprocess

            self._model = AutoModel(
                model="FunAudioLLM/SenseVoiceSmall",
                device="cuda:0",
                hub="hf",
            )
            self._post = rich_transcription_postprocess
            self._ready = True
        except Exception as exc:  # pragma: no cover
            self._init_error = str(exc)
            logger.warning("ASR fallback mode: %s", exc)

    async def transcribe(self, audio_16k: np.ndarray) -> str:
        self._ensure_loaded()
        if self._ready and self._model is not None and self._post is not None:
            res = self._model.generate(
                input=audio_16k,
                cache={},
                language="zh",
                use_itn=True,
            )
            return self._post(res[0]["text"])

        # Fallback for initial bring-up
        return "（ASR降级）语音已接收"

    @property
    def health(self) -> dict:
        return {"ready": self._ready, "attempted": self._attempted, "error": self._init_error}
