"""FikoYT XTTS v2 — Coqui TTS XTTS_v2, 16 dil, ses klonlama.

MVD'de tts-studio'nun 3. motoru. Singleton cache ile model bir kere yüklenir.
"""
import os
import tempfile

try:
    import torch
    import torchaudio
except ImportError:
    torch = None

try:
    from TTS.api import TTS
    _HAS_XTTS = True
except ImportError:
    _HAS_XTTS = False


_XTTS_LANGS = ["tr", "en", "de", "fr", "es", "ar", "ja", "ko",
               "zh-cn", "ru", "pt", "it", "pl", "nl", "hi", "cs"]

_MODEL_CACHE = {"tts": None, "device": None}


def _get_tts(device: str):
    if _MODEL_CACHE["tts"] is not None and _MODEL_CACHE["device"] == device:
        return _MODEL_CACHE["tts"]
    if not _HAS_XTTS:
        raise RuntimeError(
            "Coqui TTS yüklü değil. Kurulum: "
            "python_embeded\\python.exe -m pip install TTS"
        )
    os.environ.setdefault("COQUI_TOS_AGREED", "1")
    tts = TTS("tts_models/multilingual/multi-dataset/xtts_v2").to(device)
    _MODEL_CACHE["tts"] = tts
    _MODEL_CACHE["device"] = device
    return tts


def _write_audio_temp(audio_dict) -> str:
    """ComfyUI AUDIO dict → geçici WAV path."""
    waveform = audio_dict["waveform"]
    sr = int(audio_dict["sample_rate"])
    if waveform.dim() == 3:
        waveform = waveform[0]
    tmp = tempfile.NamedTemporaryFile(suffix=".wav", delete=False)
    tmp.close()
    torchaudio.save(tmp.name, waveform.cpu(), sr)
    return tmp.name


class FikoYTXTTSv2:
    @classmethod
    def INPUT_TYPES(cls):
        return {
            "required": {
                "text": ("STRING", {"multiline": True, "default": "Merhaba, ben yapay zeka ile klonlanmış bir ses."}),
                "reference_audio": ("AUDIO",),
                "language": (_XTTS_LANGS, {"default": "tr"}),
                "device": (["cuda", "cpu"], {"default": "cuda"}),
                "speed": ("FLOAT", {"default": 1.0, "min": 0.5, "max": 2.0, "step": 0.05}),
            }
        }

    RETURN_TYPES = ("AUDIO",)
    FUNCTION = "synthesize"
    CATEGORY = "FikoYT/audio"

    def synthesize(self, text, reference_audio, language, device, speed):
        if torch is None:
            raise RuntimeError("torch yüklü değil")
        if device == "cuda" and not torch.cuda.is_available():
            device = "cpu"

        tts = _get_tts(device)
        ref_path = _write_audio_temp(reference_audio)
        out_path = tempfile.NamedTemporaryFile(suffix=".wav", delete=False)
        out_path.close()

        try:
            tts.tts_to_file(
                text=text,
                speaker_wav=ref_path,
                language=language,
                file_path=out_path.name,
                speed=speed,
            )
            waveform, sr = torchaudio.load(out_path.name)
            if waveform.dim() == 2:
                waveform = waveform.unsqueeze(0)
            return ({"waveform": waveform, "sample_rate": sr},)
        finally:
            for p in (ref_path, out_path.name):
                try:
                    os.unlink(p)
                except Exception:
                    pass


NODE_CLASS_MAPPINGS = {"FikoYTXTTSv2": FikoYTXTTSv2}
NODE_DISPLAY_NAME_MAPPINGS = {"FikoYTXTTSv2": "FikoYT • XTTS v2 (Coqui)"}
