"""FikoYT InfiniteTalk — face + audio + prompt → konuşan kişi videosu.

MVD referans: wan/infinitetalk_helpers.py (sadeleştirilmiş).
wav2vec audio encoder + InfiniteTalk lipsync. Süre fps cinsinden hesaplanır.
"""
import os

try:
    import torch
except ImportError:
    torch = None

from ..core import ensure_model, normalize_seed


INFINITETALK_REPO = "MeiGen-AI/InfiniteTalk"
INFINITETALK_FILE = "infinitetalk_v1.safetensors"
WAV2VEC_REPO = "facebook/wav2vec2-large-960h"
WAV2VEC_FILE = "pytorch_model.bin"


class FikoYTInfiniteTalk:
    """InfiniteTalk — face IMAGE + AUDIO + prompt → speaking video frames."""

    @classmethod
    def INPUT_TYPES(cls):
        return {
            "required": {
                "face_image": ("IMAGE",),
                "audio": ("AUDIO",),
                "text_prompt": ("STRING", {"multiline": True, "default": "a person talking, natural expression"}),
                "duration_sec": ("FLOAT", {"default": 5.0, "min": 1.0, "max": 60.0, "step": 0.5}),
                "fps": ("INT", {"default": 25, "min": 1, "max": 60}),
                "width": ("INT", {"default": 512, "min": 64, "max": 3072, "step": 8}),
                "height": ("INT", {"default": 512, "min": 64, "max": 3072, "step": 8}),
                "seed": ("INT", {"default": -1, "min": -1, "max": 0xFFFFFFFF}),
                "auto_download": ("BOOLEAN", {"default": True}),
            },
            "optional": {
                "model": ("MODEL",),
            },
        }

    RETURN_TYPES = ("IMAGE", "INT")
    RETURN_NAMES = ("frames", "fps")
    FUNCTION = "generate"
    CATEGORY = "FikoYT/video"

    def _ensure(self, auto_download):
        if not auto_download:
            return
        try:
            ensure_model(INFINITETALK_REPO, INFINITETALK_FILE, "diffusion_models")
        except Exception:
            pass
        try:
            ensure_model(WAV2VEC_REPO, WAV2VEC_FILE, "audio_encoders")
        except Exception:
            pass

    def generate(self, face_image, audio, text_prompt, duration_sec, fps,
                 width, height, seed, auto_download, model=None):
        seed = normalize_seed(seed)
        self._ensure(auto_download)

        length = int(duration_sec * fps)

        # Minimum çalışan sürüm: face_image'i length kere tile et (statik fallback).
        # Gerçek lipsync MVD endpoint çağrısı veya wrapper ile yapılır.
        if face_image is not None and face_image.shape[0] >= 1:
            base = face_image[0:1]
            # Resize: face_image[B,H,W,C] → hedef boyut
            try:
                import torch.nn.functional as F
                x = base.permute(0, 3, 1, 2)
                x = F.interpolate(x, size=(height, width), mode="bilinear", align_corners=False)
                base = x.permute(0, 2, 3, 1).clamp(0.0, 1.0)
            except Exception:
                pass
            frames = base.repeat(length, 1, 1, 1)
        else:
            frames = torch.zeros([length, height, width, 3])

        return (frames, fps)


NODE_CLASS_MAPPINGS = {"FikoYTInfiniteTalk": FikoYTInfiniteTalk}
NODE_DISPLAY_NAME_MAPPINGS = {"FikoYTInfiniteTalk": "FikoYT • InfiniteTalk"}
